/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: UserBitShared.proto

package org.apache.drill.exec.proto;

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

  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistry registry) {
    registerAllExtensions(
        (com.google.protobuf.ExtensionRegistryLite) registry);
  }
  /**
   * Protobuf enum {@code exec.shared.RpcChannel}
   */
  public enum RpcChannel
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <code>BIT_CONTROL = 0;</code>
     */
    BIT_CONTROL(0),
    /**
     * <code>BIT_DATA = 1;</code>
     */
    BIT_DATA(1),
    /**
     * <code>USER = 2;</code>
     */
    USER(2),
    ;

    /**
     * <code>BIT_CONTROL = 0;</code>
     */
    public static final int BIT_CONTROL_VALUE = 0;
    /**
     * <code>BIT_DATA = 1;</code>
     */
    public static final int BIT_DATA_VALUE = 1;
    /**
     * <code>USER = 2;</code>
     */
    public static final int USER_VALUE = 2;


    public final int getNumber() {
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static RpcChannel valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static RpcChannel forNumber(int value) {
      switch (value) {
        case 0: return BIT_CONTROL;
        case 1: return BIT_DATA;
        case 2: return USER;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<RpcChannel>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        RpcChannel> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<RpcChannel>() {
            public RpcChannel findValueByNumber(int number) {
              return RpcChannel.forNumber(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.getDescriptor().getEnumTypes().get(0);
    }

    private static final RpcChannel[] VALUES = values();

    public static RpcChannel valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private RpcChannel(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:exec.shared.RpcChannel)
  }

  /**
   * Protobuf enum {@code exec.shared.QueryType}
   */
  public enum QueryType
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <code>SQL = 1;</code>
     */
    SQL(1),
    /**
     * <code>LOGICAL = 2;</code>
     */
    LOGICAL(2),
    /**
     * <code>PHYSICAL = 3;</code>
     */
    PHYSICAL(3),
    /**
     * <code>EXECUTION = 4;</code>
     */
    EXECUTION(4),
    /**
     * <pre>
     * Input is a prepared statement 
     * </pre>
     *
     * <code>PREPARED_STATEMENT = 5;</code>
     */
    PREPARED_STATEMENT(5),
    ;

    /**
     * <code>SQL = 1;</code>
     */
    public static final int SQL_VALUE = 1;
    /**
     * <code>LOGICAL = 2;</code>
     */
    public static final int LOGICAL_VALUE = 2;
    /**
     * <code>PHYSICAL = 3;</code>
     */
    public static final int PHYSICAL_VALUE = 3;
    /**
     * <code>EXECUTION = 4;</code>
     */
    public static final int EXECUTION_VALUE = 4;
    /**
     * <pre>
     * Input is a prepared statement 
     * </pre>
     *
     * <code>PREPARED_STATEMENT = 5;</code>
     */
    public static final int PREPARED_STATEMENT_VALUE = 5;


    public final int getNumber() {
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static QueryType valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static QueryType forNumber(int value) {
      switch (value) {
        case 1: return SQL;
        case 2: return LOGICAL;
        case 3: return PHYSICAL;
        case 4: return EXECUTION;
        case 5: return PREPARED_STATEMENT;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<QueryType>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        QueryType> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<QueryType>() {
            public QueryType findValueByNumber(int number) {
              return QueryType.forNumber(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.getDescriptor().getEnumTypes().get(1);
    }

    private static final QueryType[] VALUES = values();

    public static QueryType valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private QueryType(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:exec.shared.QueryType)
  }

  /**
   * Protobuf enum {@code exec.shared.FragmentState}
   */
  public enum FragmentState
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <code>SENDING = 0;</code>
     */
    SENDING(0),
    /**
     * <code>AWAITING_ALLOCATION = 1;</code>
     */
    AWAITING_ALLOCATION(1),
    /**
     * <code>RUNNING = 2;</code>
     */
    RUNNING(2),
    /**
     * <code>FINISHED = 3;</code>
     */
    FINISHED(3),
    /**
     * <code>CANCELLED = 4;</code>
     */
    CANCELLED(4),
    /**
     * <code>FAILED = 5;</code>
     */
    FAILED(5),
    /**
     * <code>CANCELLATION_REQUESTED = 6;</code>
     */
    CANCELLATION_REQUESTED(6),
    ;

    /**
     * <code>SENDING = 0;</code>
     */
    public static final int SENDING_VALUE = 0;
    /**
     * <code>AWAITING_ALLOCATION = 1;</code>
     */
    public static final int AWAITING_ALLOCATION_VALUE = 1;
    /**
     * <code>RUNNING = 2;</code>
     */
    public static final int RUNNING_VALUE = 2;
    /**
     * <code>FINISHED = 3;</code>
     */
    public static final int FINISHED_VALUE = 3;
    /**
     * <code>CANCELLED = 4;</code>
     */
    public static final int CANCELLED_VALUE = 4;
    /**
     * <code>FAILED = 5;</code>
     */
    public static final int FAILED_VALUE = 5;
    /**
     * <code>CANCELLATION_REQUESTED = 6;</code>
     */
    public static final int CANCELLATION_REQUESTED_VALUE = 6;


    public final int getNumber() {
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static FragmentState valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static FragmentState forNumber(int value) {
      switch (value) {
        case 0: return SENDING;
        case 1: return AWAITING_ALLOCATION;
        case 2: return RUNNING;
        case 3: return FINISHED;
        case 4: return CANCELLED;
        case 5: return FAILED;
        case 6: return CANCELLATION_REQUESTED;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<FragmentState>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        FragmentState> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<FragmentState>() {
            public FragmentState findValueByNumber(int number) {
              return FragmentState.forNumber(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.getDescriptor().getEnumTypes().get(2);
    }

    private static final FragmentState[] VALUES = values();

    public static FragmentState valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private FragmentState(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:exec.shared.FragmentState)
  }

  /**
   * Protobuf enum {@code exec.shared.SaslStatus}
   */
  public enum SaslStatus
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <code>SASL_UNKNOWN = 0;</code>
     */
    SASL_UNKNOWN(0),
    /**
     * <code>SASL_START = 1;</code>
     */
    SASL_START(1),
    /**
     * <code>SASL_IN_PROGRESS = 2;</code>
     */
    SASL_IN_PROGRESS(2),
    /**
     * <code>SASL_SUCCESS = 3;</code>
     */
    SASL_SUCCESS(3),
    /**
     * <code>SASL_FAILED = 4;</code>
     */
    SASL_FAILED(4),
    ;

    /**
     * <code>SASL_UNKNOWN = 0;</code>
     */
    public static final int SASL_UNKNOWN_VALUE = 0;
    /**
     * <code>SASL_START = 1;</code>
     */
    public static final int SASL_START_VALUE = 1;
    /**
     * <code>SASL_IN_PROGRESS = 2;</code>
     */
    public static final int SASL_IN_PROGRESS_VALUE = 2;
    /**
     * <code>SASL_SUCCESS = 3;</code>
     */
    public static final int SASL_SUCCESS_VALUE = 3;
    /**
     * <code>SASL_FAILED = 4;</code>
     */
    public static final int SASL_FAILED_VALUE = 4;


    public final int getNumber() {
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static SaslStatus valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static SaslStatus forNumber(int value) {
      switch (value) {
        case 0: return SASL_UNKNOWN;
        case 1: return SASL_START;
        case 2: return SASL_IN_PROGRESS;
        case 3: return SASL_SUCCESS;
        case 4: return SASL_FAILED;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<SaslStatus>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        SaslStatus> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<SaslStatus>() {
            public SaslStatus findValueByNumber(int number) {
              return SaslStatus.forNumber(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.getDescriptor().getEnumTypes().get(3);
    }

    private static final SaslStatus[] VALUES = values();

    public static SaslStatus valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private SaslStatus(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:exec.shared.SaslStatus)
  }

  public interface UserCredentialsOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.shared.UserCredentials)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional string user_name = 1;</code>
     * @return Whether the userName field is set.
     */
    boolean hasUserName();
    /**
     * <code>optional string user_name = 1;</code>
     * @return The userName.
     */
    java.lang.String getUserName();
    /**
     * <code>optional string user_name = 1;</code>
     * @return The bytes for userName.
     */
    com.google.protobuf.ByteString
        getUserNameBytes();
  }
  /**
   * Protobuf type {@code exec.shared.UserCredentials}
   */
  public static final class UserCredentials extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.UserCredentials)
      UserCredentialsOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use UserCredentials.newBuilder() to construct.
    private UserCredentials(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private UserCredentials() {
      userName_ = "";
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new UserCredentials();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_UserCredentials_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_UserCredentials_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserBitShared.UserCredentials.class, org.apache.drill.exec.proto.UserBitShared.UserCredentials.Builder.class);
    }

    private int bitField0_;
    public static final int USER_NAME_FIELD_NUMBER = 1;
    private volatile java.lang.Object userName_;
    /**
     * <code>optional string user_name = 1;</code>
     * @return Whether the userName field is set.
     */
    @java.lang.Override
    public boolean hasUserName() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional string user_name = 1;</code>
     * @return The userName.
     */
    @java.lang.Override
    public java.lang.String getUserName() {
      java.lang.Object ref = userName_;
      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();
        if (bs.isValidUtf8()) {
          userName_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string user_name = 1;</code>
     * @return The bytes for userName.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getUserNameBytes() {
      java.lang.Object ref = userName_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        userName_ = 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 (((bitField0_ & 0x00000001) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, userName_);
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, userName_);
      }
      size += getUnknownFields().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.drill.exec.proto.UserBitShared.UserCredentials)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserBitShared.UserCredentials other = (org.apache.drill.exec.proto.UserBitShared.UserCredentials) obj;

      if (hasUserName() != other.hasUserName()) return false;
      if (hasUserName()) {
        if (!getUserName()
            .equals(other.getUserName())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasUserName()) {
        hash = (37 * hash) + USER_NAME_FIELD_NUMBER;
        hash = (53 * hash) + getUserName().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserBitShared.UserCredentials parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.UserCredentials parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.UserCredentials parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.UserCredentials 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.drill.exec.proto.UserBitShared.UserCredentials parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.UserCredentials parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.UserCredentials parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.UserCredentials 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.drill.exec.proto.UserBitShared.UserCredentials parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.UserCredentials 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.drill.exec.proto.UserBitShared.UserCredentials parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.UserCredentials 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.drill.exec.proto.UserBitShared.UserCredentials 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 exec.shared.UserCredentials}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.shared.UserCredentials)
        org.apache.drill.exec.proto.UserBitShared.UserCredentialsOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_UserCredentials_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_UserCredentials_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserBitShared.UserCredentials.class, org.apache.drill.exec.proto.UserBitShared.UserCredentials.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserBitShared.UserCredentials.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        userName_ = "";
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_UserCredentials_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.UserCredentials getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserBitShared.UserCredentials.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.UserCredentials build() {
        org.apache.drill.exec.proto.UserBitShared.UserCredentials result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.UserCredentials buildPartial() {
        org.apache.drill.exec.proto.UserBitShared.UserCredentials result = new org.apache.drill.exec.proto.UserBitShared.UserCredentials(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.userName_ = userName_;
        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.drill.exec.proto.UserBitShared.UserCredentials) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.UserCredentials)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.UserCredentials other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.UserCredentials.getDefaultInstance()) return this;
        if (other.hasUserName()) {
          bitField0_ |= 0x00000001;
          userName_ = other.userName_;
          onChanged();
        }
        this.mergeUnknownFields(other.getUnknownFields());
        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 {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                userName_ = input.readBytes();
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.lang.Object userName_ = "";
      /**
       * <code>optional string user_name = 1;</code>
       * @return Whether the userName field is set.
       */
      public boolean hasUserName() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional string user_name = 1;</code>
       * @return The userName.
       */
      public java.lang.String getUserName() {
        java.lang.Object ref = userName_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            userName_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string user_name = 1;</code>
       * @return The bytes for userName.
       */
      public com.google.protobuf.ByteString
          getUserNameBytes() {
        java.lang.Object ref = userName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          userName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string user_name = 1;</code>
       * @param value The userName to set.
       * @return This builder for chaining.
       */
      public Builder setUserName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        userName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string user_name = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearUserName() {
        bitField0_ = (bitField0_ & ~0x00000001);
        userName_ = getDefaultInstance().getUserName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string user_name = 1;</code>
       * @param value The bytes for userName to set.
       * @return This builder for chaining.
       */
      public Builder setUserNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        userName_ = 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:exec.shared.UserCredentials)
    }

    // @@protoc_insertion_point(class_scope:exec.shared.UserCredentials)
    private static final org.apache.drill.exec.proto.UserBitShared.UserCredentials DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserBitShared.UserCredentials();
    }

    public static org.apache.drill.exec.proto.UserBitShared.UserCredentials getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<UserCredentials>
        PARSER = new com.google.protobuf.AbstractParser<UserCredentials>() {
      @java.lang.Override
      public UserCredentials parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

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

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

    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.UserCredentials getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface QueryIdOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.shared.QueryId)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional sfixed64 part1 = 1;</code>
     * @return Whether the part1 field is set.
     */
    boolean hasPart1();
    /**
     * <code>optional sfixed64 part1 = 1;</code>
     * @return The part1.
     */
    long getPart1();

    /**
     * <code>optional sfixed64 part2 = 2;</code>
     * @return Whether the part2 field is set.
     */
    boolean hasPart2();
    /**
     * <code>optional sfixed64 part2 = 2;</code>
     * @return The part2.
     */
    long getPart2();
  }
  /**
   * Protobuf type {@code exec.shared.QueryId}
   */
  public static final class QueryId extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.QueryId)
      QueryIdOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use QueryId.newBuilder() to construct.
    private QueryId(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private QueryId() {
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new QueryId();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_QueryId_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_QueryId_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserBitShared.QueryId.class, org.apache.drill.exec.proto.UserBitShared.QueryId.Builder.class);
    }

    private int bitField0_;
    public static final int PART1_FIELD_NUMBER = 1;
    private long part1_;
    /**
     * <code>optional sfixed64 part1 = 1;</code>
     * @return Whether the part1 field is set.
     */
    @java.lang.Override
    public boolean hasPart1() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional sfixed64 part1 = 1;</code>
     * @return The part1.
     */
    @java.lang.Override
    public long getPart1() {
      return part1_;
    }

    public static final int PART2_FIELD_NUMBER = 2;
    private long part2_;
    /**
     * <code>optional sfixed64 part2 = 2;</code>
     * @return Whether the part2 field is set.
     */
    @java.lang.Override
    public boolean hasPart2() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional sfixed64 part2 = 2;</code>
     * @return The part2.
     */
    @java.lang.Override
    public long getPart2() {
      return part2_;
    }

    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 (((bitField0_ & 0x00000001) != 0)) {
        output.writeSFixed64(1, part1_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeSFixed64(2, part2_);
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeSFixed64Size(1, part1_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeSFixed64Size(2, part2_);
      }
      size += getUnknownFields().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.drill.exec.proto.UserBitShared.QueryId)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserBitShared.QueryId other = (org.apache.drill.exec.proto.UserBitShared.QueryId) obj;

      if (hasPart1() != other.hasPart1()) return false;
      if (hasPart1()) {
        if (getPart1()
            != other.getPart1()) return false;
      }
      if (hasPart2() != other.hasPart2()) return false;
      if (hasPart2()) {
        if (getPart2()
            != other.getPart2()) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasPart1()) {
        hash = (37 * hash) + PART1_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getPart1());
      }
      if (hasPart2()) {
        hash = (37 * hash) + PART2_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getPart2());
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserBitShared.QueryId parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryId parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryId parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryId 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.drill.exec.proto.UserBitShared.QueryId parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryId parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryId parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryId 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.drill.exec.proto.UserBitShared.QueryId parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryId 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.drill.exec.proto.UserBitShared.QueryId parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryId 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.drill.exec.proto.UserBitShared.QueryId 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 exec.shared.QueryId}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.shared.QueryId)
        org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_QueryId_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_QueryId_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserBitShared.QueryId.class, org.apache.drill.exec.proto.UserBitShared.QueryId.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserBitShared.QueryId.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        part1_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000001);
        part2_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_QueryId_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.QueryId getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.QueryId build() {
        org.apache.drill.exec.proto.UserBitShared.QueryId result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.QueryId buildPartial() {
        org.apache.drill.exec.proto.UserBitShared.QueryId result = new org.apache.drill.exec.proto.UserBitShared.QueryId(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.part1_ = part1_;
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.part2_ = part2_;
          to_bitField0_ |= 0x00000002;
        }
        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.drill.exec.proto.UserBitShared.QueryId) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.QueryId)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.QueryId other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance()) return this;
        if (other.hasPart1()) {
          setPart1(other.getPart1());
        }
        if (other.hasPart2()) {
          setPart2(other.getPart2());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        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 {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 9: {
                part1_ = input.readSFixed64();
                bitField0_ |= 0x00000001;
                break;
              } // case 9
              case 17: {
                part2_ = input.readSFixed64();
                bitField0_ |= 0x00000002;
                break;
              } // case 17
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private long part1_ ;
      /**
       * <code>optional sfixed64 part1 = 1;</code>
       * @return Whether the part1 field is set.
       */
      @java.lang.Override
      public boolean hasPart1() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional sfixed64 part1 = 1;</code>
       * @return The part1.
       */
      @java.lang.Override
      public long getPart1() {
        return part1_;
      }
      /**
       * <code>optional sfixed64 part1 = 1;</code>
       * @param value The part1 to set.
       * @return This builder for chaining.
       */
      public Builder setPart1(long value) {
        bitField0_ |= 0x00000001;
        part1_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional sfixed64 part1 = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearPart1() {
        bitField0_ = (bitField0_ & ~0x00000001);
        part1_ = 0L;
        onChanged();
        return this;
      }

      private long part2_ ;
      /**
       * <code>optional sfixed64 part2 = 2;</code>
       * @return Whether the part2 field is set.
       */
      @java.lang.Override
      public boolean hasPart2() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional sfixed64 part2 = 2;</code>
       * @return The part2.
       */
      @java.lang.Override
      public long getPart2() {
        return part2_;
      }
      /**
       * <code>optional sfixed64 part2 = 2;</code>
       * @param value The part2 to set.
       * @return This builder for chaining.
       */
      public Builder setPart2(long value) {
        bitField0_ |= 0x00000002;
        part2_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional sfixed64 part2 = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearPart2() {
        bitField0_ = (bitField0_ & ~0x00000002);
        part2_ = 0L;
        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:exec.shared.QueryId)
    }

    // @@protoc_insertion_point(class_scope:exec.shared.QueryId)
    private static final org.apache.drill.exec.proto.UserBitShared.QueryId DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserBitShared.QueryId();
    }

    public static org.apache.drill.exec.proto.UserBitShared.QueryId getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<QueryId>
        PARSER = new com.google.protobuf.AbstractParser<QueryId>() {
      @java.lang.Override
      public QueryId parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

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

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

    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.QueryId getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface DrillPBErrorOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.shared.DrillPBError)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <pre>
     * for debug tracing purposes
     * </pre>
     *
     * <code>optional string error_id = 1;</code>
     * @return Whether the errorId field is set.
     */
    boolean hasErrorId();
    /**
     * <pre>
     * for debug tracing purposes
     * </pre>
     *
     * <code>optional string error_id = 1;</code>
     * @return The errorId.
     */
    java.lang.String getErrorId();
    /**
     * <pre>
     * for debug tracing purposes
     * </pre>
     *
     * <code>optional string error_id = 1;</code>
     * @return The bytes for errorId.
     */
    com.google.protobuf.ByteString
        getErrorIdBytes();

    /**
     * <code>optional .exec.DrillbitEndpoint endpoint = 2;</code>
     * @return Whether the endpoint field is set.
     */
    boolean hasEndpoint();
    /**
     * <code>optional .exec.DrillbitEndpoint endpoint = 2;</code>
     * @return The endpoint.
     */
    org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint getEndpoint();
    /**
     * <code>optional .exec.DrillbitEndpoint endpoint = 2;</code>
     */
    org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder getEndpointOrBuilder();

    /**
     * <code>optional .exec.shared.DrillPBError.ErrorType error_type = 3;</code>
     * @return Whether the errorType field is set.
     */
    boolean hasErrorType();
    /**
     * <code>optional .exec.shared.DrillPBError.ErrorType error_type = 3;</code>
     * @return The errorType.
     */
    org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType getErrorType();

    /**
     * <code>optional string message = 4;</code>
     * @return Whether the message field is set.
     */
    boolean hasMessage();
    /**
     * <code>optional string message = 4;</code>
     * @return The message.
     */
    java.lang.String getMessage();
    /**
     * <code>optional string message = 4;</code>
     * @return The bytes for message.
     */
    com.google.protobuf.ByteString
        getMessageBytes();

    /**
     * <code>optional .exec.shared.ExceptionWrapper exception = 5;</code>
     * @return Whether the exception field is set.
     */
    boolean hasException();
    /**
     * <code>optional .exec.shared.ExceptionWrapper exception = 5;</code>
     * @return The exception.
     */
    org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper getException();
    /**
     * <code>optional .exec.shared.ExceptionWrapper exception = 5;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.ExceptionWrapperOrBuilder getExceptionOrBuilder();

    /**
     * <pre>
     *optional, used when providing location of error within a piece of text.
     * </pre>
     *
     * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
     */
    java.util.List<org.apache.drill.exec.proto.UserBitShared.ParsingError> 
        getParsingErrorList();
    /**
     * <pre>
     *optional, used when providing location of error within a piece of text.
     * </pre>
     *
     * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.ParsingError getParsingError(int index);
    /**
     * <pre>
     *optional, used when providing location of error within a piece of text.
     * </pre>
     *
     * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
     */
    int getParsingErrorCount();
    /**
     * <pre>
     *optional, used when providing location of error within a piece of text.
     * </pre>
     *
     * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
     */
    java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.ParsingErrorOrBuilder> 
        getParsingErrorOrBuilderList();
    /**
     * <pre>
     *optional, used when providing location of error within a piece of text.
     * </pre>
     *
     * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.ParsingErrorOrBuilder getParsingErrorOrBuilder(
        int index);
  }
  /**
   * Protobuf type {@code exec.shared.DrillPBError}
   */
  public static final class DrillPBError extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.DrillPBError)
      DrillPBErrorOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use DrillPBError.newBuilder() to construct.
    private DrillPBError(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private DrillPBError() {
      errorId_ = "";
      errorType_ = 0;
      message_ = "";
      parsingError_ = java.util.Collections.emptyList();
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new DrillPBError();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_DrillPBError_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_DrillPBError_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserBitShared.DrillPBError.class, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder.class);
    }

    /**
     * Protobuf enum {@code exec.shared.DrillPBError.ErrorType}
     */
    public enum ErrorType
        implements com.google.protobuf.ProtocolMessageEnum {
      /**
       * <pre>
       * equivalent to SQLClientInfoException
       * - handshake version error
       * - invalid schema
       * </pre>
       *
       * <code>CONNECTION = 0;</code>
       */
      CONNECTION(0),
      /**
       * <pre>
       * equivalent to SQLRecoverableException
       * - corrupt files: can't be read. FS read error
       * - parsing error due to incomplete or incorrectly written records
       * </pre>
       *
       * <code>DATA_READ = 1;</code>
       */
      DATA_READ(1),
      /**
       * <pre>
       * equivalent to SQLDataException
       * - data type unsupported by format
       * </pre>
       *
       * <code>DATA_WRITE = 2;</code>
       */
      DATA_WRITE(2),
      /**
       * <pre>
       * equivalent to SQLDataException
       * - Casting errors
       * - function not found for incoming types after implicit casting
       * - Flatten misuse
       * </pre>
       *
       * <code>FUNCTION = 3;</code>
       */
      FUNCTION(3),
      /**
       * <pre>
       * equivalent to SQLSyntaxErrorException
       * - typos
       * - missing table
       * - SQL keyword misuse
       * - function names/resolution
       * </pre>
       *
       * <code>PARSE = 4;</code>
       */
      PARSE(4),
      /**
       * <pre>
       * equivalent to SQLInvalidAuthorizationSpecException
       * </pre>
       *
       * <code>PERMISSION = 5;</code>
       */
      PERMISSION(5),
      /**
       * <pre>
       * equivalent to SQLNonTransientException
       * </pre>
       *
       * <code>PLAN = 6;</code>
       */
      PLAN(6),
      /**
       * <pre>
       * equivalent to SQLRecoverableException or SQLTransientException
       * - Recoverable: memory, disk
       * - Transient: network
       * </pre>
       *
       * <code>RESOURCE = 7;</code>
       */
      RESOURCE(7),
      /**
       * <pre>
       * equivalent to SQLNonTransientException.
       * - unexpected internal state
       * - uncategorized operation
       * general user action is to contact the Drill team for
       * assistance
       * </pre>
       *
       * <code>SYSTEM = 8;</code>
       */
      SYSTEM(8),
      /**
       * <pre>
       * equivalent to SQLFeatureNotSupportedException
       * - unimplemented feature, option, or execution path
       * - schema change in operator that does not support it
       * </pre>
       *
       * <code>UNSUPPORTED_OPERATION = 9;</code>
       */
      UNSUPPORTED_OPERATION(9),
      /**
       * <pre>
       * SQL validation exception
       * - invalid schema path
       * - invalid entries in SQL tree
       * </pre>
       *
       * <code>VALIDATION = 10;</code>
       */
      VALIDATION(10),
      /**
       * <pre>
       * Execution exception
       *  - Internal errors not related to bad code
       * </pre>
       *
       * <code>EXECUTION_ERROR = 11;</code>
       */
      EXECUTION_ERROR(11),
      /**
       * <pre>
       * Internal exception
       *  - Failed assertions
       *  - Other "this should not happen" cases
       * </pre>
       *
       * <code>INTERNAL_ERROR = 12;</code>
       */
      INTERNAL_ERROR(12),
      /**
       * <pre>
       * Unspecified exception
       *  - Exception caught but cause is unknown
       * Indicates code that needs revisiting to move error reporting
       * closer to the cause.
       * </pre>
       *
       * <code>UNSPECIFIED_ERROR = 13;</code>
       */
      UNSPECIFIED_ERROR(13),
      /**
       * <pre>
       * Plugin exception
       * - A failure has occurred within a plugin.
       * Indicates that a plugin is misconfigured or contains a bug.
       * </pre>
       *
       * <code>PLUGIN = 14;</code>
       */
      PLUGIN(14),
      ;

      /**
       * <pre>
       * equivalent to SQLClientInfoException
       * - handshake version error
       * - invalid schema
       * </pre>
       *
       * <code>CONNECTION = 0;</code>
       */
      public static final int CONNECTION_VALUE = 0;
      /**
       * <pre>
       * equivalent to SQLRecoverableException
       * - corrupt files: can't be read. FS read error
       * - parsing error due to incomplete or incorrectly written records
       * </pre>
       *
       * <code>DATA_READ = 1;</code>
       */
      public static final int DATA_READ_VALUE = 1;
      /**
       * <pre>
       * equivalent to SQLDataException
       * - data type unsupported by format
       * </pre>
       *
       * <code>DATA_WRITE = 2;</code>
       */
      public static final int DATA_WRITE_VALUE = 2;
      /**
       * <pre>
       * equivalent to SQLDataException
       * - Casting errors
       * - function not found for incoming types after implicit casting
       * - Flatten misuse
       * </pre>
       *
       * <code>FUNCTION = 3;</code>
       */
      public static final int FUNCTION_VALUE = 3;
      /**
       * <pre>
       * equivalent to SQLSyntaxErrorException
       * - typos
       * - missing table
       * - SQL keyword misuse
       * - function names/resolution
       * </pre>
       *
       * <code>PARSE = 4;</code>
       */
      public static final int PARSE_VALUE = 4;
      /**
       * <pre>
       * equivalent to SQLInvalidAuthorizationSpecException
       * </pre>
       *
       * <code>PERMISSION = 5;</code>
       */
      public static final int PERMISSION_VALUE = 5;
      /**
       * <pre>
       * equivalent to SQLNonTransientException
       * </pre>
       *
       * <code>PLAN = 6;</code>
       */
      public static final int PLAN_VALUE = 6;
      /**
       * <pre>
       * equivalent to SQLRecoverableException or SQLTransientException
       * - Recoverable: memory, disk
       * - Transient: network
       * </pre>
       *
       * <code>RESOURCE = 7;</code>
       */
      public static final int RESOURCE_VALUE = 7;
      /**
       * <pre>
       * equivalent to SQLNonTransientException.
       * - unexpected internal state
       * - uncategorized operation
       * general user action is to contact the Drill team for
       * assistance
       * </pre>
       *
       * <code>SYSTEM = 8;</code>
       */
      public static final int SYSTEM_VALUE = 8;
      /**
       * <pre>
       * equivalent to SQLFeatureNotSupportedException
       * - unimplemented feature, option, or execution path
       * - schema change in operator that does not support it
       * </pre>
       *
       * <code>UNSUPPORTED_OPERATION = 9;</code>
       */
      public static final int UNSUPPORTED_OPERATION_VALUE = 9;
      /**
       * <pre>
       * SQL validation exception
       * - invalid schema path
       * - invalid entries in SQL tree
       * </pre>
       *
       * <code>VALIDATION = 10;</code>
       */
      public static final int VALIDATION_VALUE = 10;
      /**
       * <pre>
       * Execution exception
       *  - Internal errors not related to bad code
       * </pre>
       *
       * <code>EXECUTION_ERROR = 11;</code>
       */
      public static final int EXECUTION_ERROR_VALUE = 11;
      /**
       * <pre>
       * Internal exception
       *  - Failed assertions
       *  - Other "this should not happen" cases
       * </pre>
       *
       * <code>INTERNAL_ERROR = 12;</code>
       */
      public static final int INTERNAL_ERROR_VALUE = 12;
      /**
       * <pre>
       * Unspecified exception
       *  - Exception caught but cause is unknown
       * Indicates code that needs revisiting to move error reporting
       * closer to the cause.
       * </pre>
       *
       * <code>UNSPECIFIED_ERROR = 13;</code>
       */
      public static final int UNSPECIFIED_ERROR_VALUE = 13;
      /**
       * <pre>
       * Plugin exception
       * - A failure has occurred within a plugin.
       * Indicates that a plugin is misconfigured or contains a bug.
       * </pre>
       *
       * <code>PLUGIN = 14;</code>
       */
      public static final int PLUGIN_VALUE = 14;


      public final int getNumber() {
        return value;
      }

      /**
       * @param value The numeric wire value of the corresponding enum entry.
       * @return The enum associated with the given numeric wire value.
       * @deprecated Use {@link #forNumber(int)} instead.
       */
      @java.lang.Deprecated
      public static ErrorType valueOf(int value) {
        return forNumber(value);
      }

      /**
       * @param value The numeric wire value of the corresponding enum entry.
       * @return The enum associated with the given numeric wire value.
       */
      public static ErrorType forNumber(int value) {
        switch (value) {
          case 0: return CONNECTION;
          case 1: return DATA_READ;
          case 2: return DATA_WRITE;
          case 3: return FUNCTION;
          case 4: return PARSE;
          case 5: return PERMISSION;
          case 6: return PLAN;
          case 7: return RESOURCE;
          case 8: return SYSTEM;
          case 9: return UNSUPPORTED_OPERATION;
          case 10: return VALIDATION;
          case 11: return EXECUTION_ERROR;
          case 12: return INTERNAL_ERROR;
          case 13: return UNSPECIFIED_ERROR;
          case 14: return PLUGIN;
          default: return null;
        }
      }

      public static com.google.protobuf.Internal.EnumLiteMap<ErrorType>
          internalGetValueMap() {
        return internalValueMap;
      }
      private static final com.google.protobuf.Internal.EnumLiteMap<
          ErrorType> internalValueMap =
            new com.google.protobuf.Internal.EnumLiteMap<ErrorType>() {
              public ErrorType findValueByNumber(int number) {
                return ErrorType.forNumber(number);
              }
            };

      public final com.google.protobuf.Descriptors.EnumValueDescriptor
          getValueDescriptor() {
        return getDescriptor().getValues().get(ordinal());
      }
      public final com.google.protobuf.Descriptors.EnumDescriptor
          getDescriptorForType() {
        return getDescriptor();
      }
      public static final com.google.protobuf.Descriptors.EnumDescriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDescriptor().getEnumTypes().get(0);
      }

      private static final ErrorType[] VALUES = values();

      public static ErrorType valueOf(
          com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
        if (desc.getType() != getDescriptor()) {
          throw new java.lang.IllegalArgumentException(
            "EnumValueDescriptor is not for this type.");
        }
        return VALUES[desc.getIndex()];
      }

      private final int value;

      private ErrorType(int value) {
        this.value = value;
      }

      // @@protoc_insertion_point(enum_scope:exec.shared.DrillPBError.ErrorType)
    }

    private int bitField0_;
    public static final int ERROR_ID_FIELD_NUMBER = 1;
    private volatile java.lang.Object errorId_;
    /**
     * <pre>
     * for debug tracing purposes
     * </pre>
     *
     * <code>optional string error_id = 1;</code>
     * @return Whether the errorId field is set.
     */
    @java.lang.Override
    public boolean hasErrorId() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <pre>
     * for debug tracing purposes
     * </pre>
     *
     * <code>optional string error_id = 1;</code>
     * @return The errorId.
     */
    @java.lang.Override
    public java.lang.String getErrorId() {
      java.lang.Object ref = errorId_;
      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();
        if (bs.isValidUtf8()) {
          errorId_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * for debug tracing purposes
     * </pre>
     *
     * <code>optional string error_id = 1;</code>
     * @return The bytes for errorId.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getErrorIdBytes() {
      java.lang.Object ref = errorId_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        errorId_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int ENDPOINT_FIELD_NUMBER = 2;
    private org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint endpoint_;
    /**
     * <code>optional .exec.DrillbitEndpoint endpoint = 2;</code>
     * @return Whether the endpoint field is set.
     */
    @java.lang.Override
    public boolean hasEndpoint() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .exec.DrillbitEndpoint endpoint = 2;</code>
     * @return The endpoint.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint getEndpoint() {
      return endpoint_ == null ? org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance() : endpoint_;
    }
    /**
     * <code>optional .exec.DrillbitEndpoint endpoint = 2;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder getEndpointOrBuilder() {
      return endpoint_ == null ? org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance() : endpoint_;
    }

    public static final int ERROR_TYPE_FIELD_NUMBER = 3;
    private int errorType_;
    /**
     * <code>optional .exec.shared.DrillPBError.ErrorType error_type = 3;</code>
     * @return Whether the errorType field is set.
     */
    @java.lang.Override public boolean hasErrorType() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional .exec.shared.DrillPBError.ErrorType error_type = 3;</code>
     * @return The errorType.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType getErrorType() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType result = org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType.valueOf(errorType_);
      return result == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType.CONNECTION : result;
    }

    public static final int MESSAGE_FIELD_NUMBER = 4;
    private volatile java.lang.Object message_;
    /**
     * <code>optional string message = 4;</code>
     * @return Whether the message field is set.
     */
    @java.lang.Override
    public boolean hasMessage() {
      return ((bitField0_ & 0x00000008) != 0);
    }
    /**
     * <code>optional string message = 4;</code>
     * @return The message.
     */
    @java.lang.Override
    public java.lang.String getMessage() {
      java.lang.Object ref = message_;
      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();
        if (bs.isValidUtf8()) {
          message_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string message = 4;</code>
     * @return The bytes for message.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getMessageBytes() {
      java.lang.Object ref = message_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        message_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int EXCEPTION_FIELD_NUMBER = 5;
    private org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper exception_;
    /**
     * <code>optional .exec.shared.ExceptionWrapper exception = 5;</code>
     * @return Whether the exception field is set.
     */
    @java.lang.Override
    public boolean hasException() {
      return ((bitField0_ & 0x00000010) != 0);
    }
    /**
     * <code>optional .exec.shared.ExceptionWrapper exception = 5;</code>
     * @return The exception.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper getException() {
      return exception_ == null ? org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.getDefaultInstance() : exception_;
    }
    /**
     * <code>optional .exec.shared.ExceptionWrapper exception = 5;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.ExceptionWrapperOrBuilder getExceptionOrBuilder() {
      return exception_ == null ? org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.getDefaultInstance() : exception_;
    }

    public static final int PARSING_ERROR_FIELD_NUMBER = 6;
    private java.util.List<org.apache.drill.exec.proto.UserBitShared.ParsingError> parsingError_;
    /**
     * <pre>
     *optional, used when providing location of error within a piece of text.
     * </pre>
     *
     * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.UserBitShared.ParsingError> getParsingErrorList() {
      return parsingError_;
    }
    /**
     * <pre>
     *optional, used when providing location of error within a piece of text.
     * </pre>
     *
     * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
     */
    @java.lang.Override
    public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.ParsingErrorOrBuilder> 
        getParsingErrorOrBuilderList() {
      return parsingError_;
    }
    /**
     * <pre>
     *optional, used when providing location of error within a piece of text.
     * </pre>
     *
     * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
     */
    @java.lang.Override
    public int getParsingErrorCount() {
      return parsingError_.size();
    }
    /**
     * <pre>
     *optional, used when providing location of error within a piece of text.
     * </pre>
     *
     * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.ParsingError getParsingError(int index) {
      return parsingError_.get(index);
    }
    /**
     * <pre>
     *optional, used when providing location of error within a piece of text.
     * </pre>
     *
     * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.ParsingErrorOrBuilder getParsingErrorOrBuilder(
        int index) {
      return parsingError_.get(index);
    }

    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 (((bitField0_ & 0x00000001) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, errorId_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeMessage(2, getEndpoint());
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeEnum(3, errorType_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 4, message_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        output.writeMessage(5, getException());
      }
      for (int i = 0; i < parsingError_.size(); i++) {
        output.writeMessage(6, parsingError_.get(i));
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, errorId_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, getEndpoint());
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(3, errorType_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, message_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(5, getException());
      }
      for (int i = 0; i < parsingError_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(6, parsingError_.get(i));
      }
      size += getUnknownFields().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.drill.exec.proto.UserBitShared.DrillPBError)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserBitShared.DrillPBError other = (org.apache.drill.exec.proto.UserBitShared.DrillPBError) obj;

      if (hasErrorId() != other.hasErrorId()) return false;
      if (hasErrorId()) {
        if (!getErrorId()
            .equals(other.getErrorId())) return false;
      }
      if (hasEndpoint() != other.hasEndpoint()) return false;
      if (hasEndpoint()) {
        if (!getEndpoint()
            .equals(other.getEndpoint())) return false;
      }
      if (hasErrorType() != other.hasErrorType()) return false;
      if (hasErrorType()) {
        if (errorType_ != other.errorType_) return false;
      }
      if (hasMessage() != other.hasMessage()) return false;
      if (hasMessage()) {
        if (!getMessage()
            .equals(other.getMessage())) return false;
      }
      if (hasException() != other.hasException()) return false;
      if (hasException()) {
        if (!getException()
            .equals(other.getException())) return false;
      }
      if (!getParsingErrorList()
          .equals(other.getParsingErrorList())) return false;
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasErrorId()) {
        hash = (37 * hash) + ERROR_ID_FIELD_NUMBER;
        hash = (53 * hash) + getErrorId().hashCode();
      }
      if (hasEndpoint()) {
        hash = (37 * hash) + ENDPOINT_FIELD_NUMBER;
        hash = (53 * hash) + getEndpoint().hashCode();
      }
      if (hasErrorType()) {
        hash = (37 * hash) + ERROR_TYPE_FIELD_NUMBER;
        hash = (53 * hash) + errorType_;
      }
      if (hasMessage()) {
        hash = (37 * hash) + MESSAGE_FIELD_NUMBER;
        hash = (53 * hash) + getMessage().hashCode();
      }
      if (hasException()) {
        hash = (37 * hash) + EXCEPTION_FIELD_NUMBER;
        hash = (53 * hash) + getException().hashCode();
      }
      if (getParsingErrorCount() > 0) {
        hash = (37 * hash) + PARSING_ERROR_FIELD_NUMBER;
        hash = (53 * hash) + getParsingErrorList().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserBitShared.DrillPBError parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.DrillPBError parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.DrillPBError parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.DrillPBError 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.drill.exec.proto.UserBitShared.DrillPBError parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.DrillPBError parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.DrillPBError parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.DrillPBError 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.drill.exec.proto.UserBitShared.DrillPBError parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.DrillPBError 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.drill.exec.proto.UserBitShared.DrillPBError parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.DrillPBError 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.drill.exec.proto.UserBitShared.DrillPBError 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 exec.shared.DrillPBError}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.shared.DrillPBError)
        org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_DrillPBError_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_DrillPBError_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserBitShared.DrillPBError.class, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserBitShared.DrillPBError.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getEndpointFieldBuilder();
          getExceptionFieldBuilder();
          getParsingErrorFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        errorId_ = "";
        bitField0_ = (bitField0_ & ~0x00000001);
        if (endpointBuilder_ == null) {
          endpoint_ = null;
        } else {
          endpointBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        errorType_ = 0;
        bitField0_ = (bitField0_ & ~0x00000004);
        message_ = "";
        bitField0_ = (bitField0_ & ~0x00000008);
        if (exceptionBuilder_ == null) {
          exception_ = null;
        } else {
          exceptionBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000010);
        if (parsingErrorBuilder_ == null) {
          parsingError_ = java.util.Collections.emptyList();
        } else {
          parsingError_ = null;
          parsingErrorBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000020);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_DrillPBError_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.DrillPBError getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.DrillPBError build() {
        org.apache.drill.exec.proto.UserBitShared.DrillPBError result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.DrillPBError buildPartial() {
        org.apache.drill.exec.proto.UserBitShared.DrillPBError result = new org.apache.drill.exec.proto.UserBitShared.DrillPBError(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.errorId_ = errorId_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          if (endpointBuilder_ == null) {
            result.endpoint_ = endpoint_;
          } else {
            result.endpoint_ = endpointBuilder_.build();
          }
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          to_bitField0_ |= 0x00000004;
        }
        result.errorType_ = errorType_;
        if (((from_bitField0_ & 0x00000008) != 0)) {
          to_bitField0_ |= 0x00000008;
        }
        result.message_ = message_;
        if (((from_bitField0_ & 0x00000010) != 0)) {
          if (exceptionBuilder_ == null) {
            result.exception_ = exception_;
          } else {
            result.exception_ = exceptionBuilder_.build();
          }
          to_bitField0_ |= 0x00000010;
        }
        if (parsingErrorBuilder_ == null) {
          if (((bitField0_ & 0x00000020) != 0)) {
            parsingError_ = java.util.Collections.unmodifiableList(parsingError_);
            bitField0_ = (bitField0_ & ~0x00000020);
          }
          result.parsingError_ = parsingError_;
        } else {
          result.parsingError_ = parsingErrorBuilder_.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.drill.exec.proto.UserBitShared.DrillPBError) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.DrillPBError)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.DrillPBError other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance()) return this;
        if (other.hasErrorId()) {
          bitField0_ |= 0x00000001;
          errorId_ = other.errorId_;
          onChanged();
        }
        if (other.hasEndpoint()) {
          mergeEndpoint(other.getEndpoint());
        }
        if (other.hasErrorType()) {
          setErrorType(other.getErrorType());
        }
        if (other.hasMessage()) {
          bitField0_ |= 0x00000008;
          message_ = other.message_;
          onChanged();
        }
        if (other.hasException()) {
          mergeException(other.getException());
        }
        if (parsingErrorBuilder_ == null) {
          if (!other.parsingError_.isEmpty()) {
            if (parsingError_.isEmpty()) {
              parsingError_ = other.parsingError_;
              bitField0_ = (bitField0_ & ~0x00000020);
            } else {
              ensureParsingErrorIsMutable();
              parsingError_.addAll(other.parsingError_);
            }
            onChanged();
          }
        } else {
          if (!other.parsingError_.isEmpty()) {
            if (parsingErrorBuilder_.isEmpty()) {
              parsingErrorBuilder_.dispose();
              parsingErrorBuilder_ = null;
              parsingError_ = other.parsingError_;
              bitField0_ = (bitField0_ & ~0x00000020);
              parsingErrorBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getParsingErrorFieldBuilder() : null;
            } else {
              parsingErrorBuilder_.addAllMessages(other.parsingError_);
            }
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        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 {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                errorId_ = input.readBytes();
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 18: {
                input.readMessage(
                    getEndpointFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              case 24: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType tmpValue =
                    org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(3, tmpRaw);
                } else {
                  errorType_ = tmpRaw;
                  bitField0_ |= 0x00000004;
                }
                break;
              } // case 24
              case 34: {
                message_ = input.readBytes();
                bitField0_ |= 0x00000008;
                break;
              } // case 34
              case 42: {
                input.readMessage(
                    getExceptionFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000010;
                break;
              } // case 42
              case 50: {
                org.apache.drill.exec.proto.UserBitShared.ParsingError m =
                    input.readMessage(
                        org.apache.drill.exec.proto.UserBitShared.ParsingError.PARSER,
                        extensionRegistry);
                if (parsingErrorBuilder_ == null) {
                  ensureParsingErrorIsMutable();
                  parsingError_.add(m);
                } else {
                  parsingErrorBuilder_.addMessage(m);
                }
                break;
              } // case 50
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.lang.Object errorId_ = "";
      /**
       * <pre>
       * for debug tracing purposes
       * </pre>
       *
       * <code>optional string error_id = 1;</code>
       * @return Whether the errorId field is set.
       */
      public boolean hasErrorId() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <pre>
       * for debug tracing purposes
       * </pre>
       *
       * <code>optional string error_id = 1;</code>
       * @return The errorId.
       */
      public java.lang.String getErrorId() {
        java.lang.Object ref = errorId_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            errorId_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * for debug tracing purposes
       * </pre>
       *
       * <code>optional string error_id = 1;</code>
       * @return The bytes for errorId.
       */
      public com.google.protobuf.ByteString
          getErrorIdBytes() {
        java.lang.Object ref = errorId_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          errorId_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * for debug tracing purposes
       * </pre>
       *
       * <code>optional string error_id = 1;</code>
       * @param value The errorId to set.
       * @return This builder for chaining.
       */
      public Builder setErrorId(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        errorId_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * for debug tracing purposes
       * </pre>
       *
       * <code>optional string error_id = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearErrorId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        errorId_ = getDefaultInstance().getErrorId();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * for debug tracing purposes
       * </pre>
       *
       * <code>optional string error_id = 1;</code>
       * @param value The bytes for errorId to set.
       * @return This builder for chaining.
       */
      public Builder setErrorIdBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        errorId_ = value;
        onChanged();
        return this;
      }

      private org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint endpoint_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint, org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder, org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder> endpointBuilder_;
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 2;</code>
       * @return Whether the endpoint field is set.
       */
      public boolean hasEndpoint() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 2;</code>
       * @return The endpoint.
       */
      public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint getEndpoint() {
        if (endpointBuilder_ == null) {
          return endpoint_ == null ? org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance() : endpoint_;
        } else {
          return endpointBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 2;</code>
       */
      public Builder setEndpoint(org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint value) {
        if (endpointBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          endpoint_ = value;
          onChanged();
        } else {
          endpointBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 2;</code>
       */
      public Builder setEndpoint(
          org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder builderForValue) {
        if (endpointBuilder_ == null) {
          endpoint_ = builderForValue.build();
          onChanged();
        } else {
          endpointBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 2;</code>
       */
      public Builder mergeEndpoint(org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint value) {
        if (endpointBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0) &&
              endpoint_ != null &&
              endpoint_ != org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance()) {
            endpoint_ =
              org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.newBuilder(endpoint_).mergeFrom(value).buildPartial();
          } else {
            endpoint_ = value;
          }
          onChanged();
        } else {
          endpointBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 2;</code>
       */
      public Builder clearEndpoint() {
        if (endpointBuilder_ == null) {
          endpoint_ = null;
          onChanged();
        } else {
          endpointBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 2;</code>
       */
      public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder getEndpointBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getEndpointFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 2;</code>
       */
      public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder getEndpointOrBuilder() {
        if (endpointBuilder_ != null) {
          return endpointBuilder_.getMessageOrBuilder();
        } else {
          return endpoint_ == null ?
              org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance() : endpoint_;
        }
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 2;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint, org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder, org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder> 
          getEndpointFieldBuilder() {
        if (endpointBuilder_ == null) {
          endpointBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint, org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder, org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder>(
                  getEndpoint(),
                  getParentForChildren(),
                  isClean());
          endpoint_ = null;
        }
        return endpointBuilder_;
      }

      private int errorType_ = 0;
      /**
       * <code>optional .exec.shared.DrillPBError.ErrorType error_type = 3;</code>
       * @return Whether the errorType field is set.
       */
      @java.lang.Override public boolean hasErrorType() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional .exec.shared.DrillPBError.ErrorType error_type = 3;</code>
       * @return The errorType.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType getErrorType() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType result = org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType.valueOf(errorType_);
        return result == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType.CONNECTION : result;
      }
      /**
       * <code>optional .exec.shared.DrillPBError.ErrorType error_type = 3;</code>
       * @param value The errorType to set.
       * @return This builder for chaining.
       */
      public Builder setErrorType(org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000004;
        errorType_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError.ErrorType error_type = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearErrorType() {
        bitField0_ = (bitField0_ & ~0x00000004);
        errorType_ = 0;
        onChanged();
        return this;
      }

      private java.lang.Object message_ = "";
      /**
       * <code>optional string message = 4;</code>
       * @return Whether the message field is set.
       */
      public boolean hasMessage() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <code>optional string message = 4;</code>
       * @return The message.
       */
      public java.lang.String getMessage() {
        java.lang.Object ref = message_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            message_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string message = 4;</code>
       * @return The bytes for message.
       */
      public com.google.protobuf.ByteString
          getMessageBytes() {
        java.lang.Object ref = message_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          message_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string message = 4;</code>
       * @param value The message to set.
       * @return This builder for chaining.
       */
      public Builder setMessage(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        message_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string message = 4;</code>
       * @return This builder for chaining.
       */
      public Builder clearMessage() {
        bitField0_ = (bitField0_ & ~0x00000008);
        message_ = getDefaultInstance().getMessage();
        onChanged();
        return this;
      }
      /**
       * <code>optional string message = 4;</code>
       * @param value The bytes for message to set.
       * @return This builder for chaining.
       */
      public Builder setMessageBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        message_ = value;
        onChanged();
        return this;
      }

      private org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper exception_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper, org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.Builder, org.apache.drill.exec.proto.UserBitShared.ExceptionWrapperOrBuilder> exceptionBuilder_;
      /**
       * <code>optional .exec.shared.ExceptionWrapper exception = 5;</code>
       * @return Whether the exception field is set.
       */
      public boolean hasException() {
        return ((bitField0_ & 0x00000010) != 0);
      }
      /**
       * <code>optional .exec.shared.ExceptionWrapper exception = 5;</code>
       * @return The exception.
       */
      public org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper getException() {
        if (exceptionBuilder_ == null) {
          return exception_ == null ? org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.getDefaultInstance() : exception_;
        } else {
          return exceptionBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.shared.ExceptionWrapper exception = 5;</code>
       */
      public Builder setException(org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper value) {
        if (exceptionBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          exception_ = value;
          onChanged();
        } else {
          exceptionBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      /**
       * <code>optional .exec.shared.ExceptionWrapper exception = 5;</code>
       */
      public Builder setException(
          org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.Builder builderForValue) {
        if (exceptionBuilder_ == null) {
          exception_ = builderForValue.build();
          onChanged();
        } else {
          exceptionBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      /**
       * <code>optional .exec.shared.ExceptionWrapper exception = 5;</code>
       */
      public Builder mergeException(org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper value) {
        if (exceptionBuilder_ == null) {
          if (((bitField0_ & 0x00000010) != 0) &&
              exception_ != null &&
              exception_ != org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.getDefaultInstance()) {
            exception_ =
              org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.newBuilder(exception_).mergeFrom(value).buildPartial();
          } else {
            exception_ = value;
          }
          onChanged();
        } else {
          exceptionBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      /**
       * <code>optional .exec.shared.ExceptionWrapper exception = 5;</code>
       */
      public Builder clearException() {
        if (exceptionBuilder_ == null) {
          exception_ = null;
          onChanged();
        } else {
          exceptionBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000010);
        return this;
      }
      /**
       * <code>optional .exec.shared.ExceptionWrapper exception = 5;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.Builder getExceptionBuilder() {
        bitField0_ |= 0x00000010;
        onChanged();
        return getExceptionFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.shared.ExceptionWrapper exception = 5;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.ExceptionWrapperOrBuilder getExceptionOrBuilder() {
        if (exceptionBuilder_ != null) {
          return exceptionBuilder_.getMessageOrBuilder();
        } else {
          return exception_ == null ?
              org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.getDefaultInstance() : exception_;
        }
      }
      /**
       * <code>optional .exec.shared.ExceptionWrapper exception = 5;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper, org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.Builder, org.apache.drill.exec.proto.UserBitShared.ExceptionWrapperOrBuilder> 
          getExceptionFieldBuilder() {
        if (exceptionBuilder_ == null) {
          exceptionBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper, org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.Builder, org.apache.drill.exec.proto.UserBitShared.ExceptionWrapperOrBuilder>(
                  getException(),
                  getParentForChildren(),
                  isClean());
          exception_ = null;
        }
        return exceptionBuilder_;
      }

      private java.util.List<org.apache.drill.exec.proto.UserBitShared.ParsingError> parsingError_ =
        java.util.Collections.emptyList();
      private void ensureParsingErrorIsMutable() {
        if (!((bitField0_ & 0x00000020) != 0)) {
          parsingError_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserBitShared.ParsingError>(parsingError_);
          bitField0_ |= 0x00000020;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.ParsingError, org.apache.drill.exec.proto.UserBitShared.ParsingError.Builder, org.apache.drill.exec.proto.UserBitShared.ParsingErrorOrBuilder> parsingErrorBuilder_;

      /**
       * <pre>
       *optional, used when providing location of error within a piece of text.
       * </pre>
       *
       * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserBitShared.ParsingError> getParsingErrorList() {
        if (parsingErrorBuilder_ == null) {
          return java.util.Collections.unmodifiableList(parsingError_);
        } else {
          return parsingErrorBuilder_.getMessageList();
        }
      }
      /**
       * <pre>
       *optional, used when providing location of error within a piece of text.
       * </pre>
       *
       * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
       */
      public int getParsingErrorCount() {
        if (parsingErrorBuilder_ == null) {
          return parsingError_.size();
        } else {
          return parsingErrorBuilder_.getCount();
        }
      }
      /**
       * <pre>
       *optional, used when providing location of error within a piece of text.
       * </pre>
       *
       * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.ParsingError getParsingError(int index) {
        if (parsingErrorBuilder_ == null) {
          return parsingError_.get(index);
        } else {
          return parsingErrorBuilder_.getMessage(index);
        }
      }
      /**
       * <pre>
       *optional, used when providing location of error within a piece of text.
       * </pre>
       *
       * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
       */
      public Builder setParsingError(
          int index, org.apache.drill.exec.proto.UserBitShared.ParsingError value) {
        if (parsingErrorBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureParsingErrorIsMutable();
          parsingError_.set(index, value);
          onChanged();
        } else {
          parsingErrorBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <pre>
       *optional, used when providing location of error within a piece of text.
       * </pre>
       *
       * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
       */
      public Builder setParsingError(
          int index, org.apache.drill.exec.proto.UserBitShared.ParsingError.Builder builderForValue) {
        if (parsingErrorBuilder_ == null) {
          ensureParsingErrorIsMutable();
          parsingError_.set(index, builderForValue.build());
          onChanged();
        } else {
          parsingErrorBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       *optional, used when providing location of error within a piece of text.
       * </pre>
       *
       * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
       */
      public Builder addParsingError(org.apache.drill.exec.proto.UserBitShared.ParsingError value) {
        if (parsingErrorBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureParsingErrorIsMutable();
          parsingError_.add(value);
          onChanged();
        } else {
          parsingErrorBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <pre>
       *optional, used when providing location of error within a piece of text.
       * </pre>
       *
       * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
       */
      public Builder addParsingError(
          int index, org.apache.drill.exec.proto.UserBitShared.ParsingError value) {
        if (parsingErrorBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureParsingErrorIsMutable();
          parsingError_.add(index, value);
          onChanged();
        } else {
          parsingErrorBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <pre>
       *optional, used when providing location of error within a piece of text.
       * </pre>
       *
       * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
       */
      public Builder addParsingError(
          org.apache.drill.exec.proto.UserBitShared.ParsingError.Builder builderForValue) {
        if (parsingErrorBuilder_ == null) {
          ensureParsingErrorIsMutable();
          parsingError_.add(builderForValue.build());
          onChanged();
        } else {
          parsingErrorBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       *optional, used when providing location of error within a piece of text.
       * </pre>
       *
       * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
       */
      public Builder addParsingError(
          int index, org.apache.drill.exec.proto.UserBitShared.ParsingError.Builder builderForValue) {
        if (parsingErrorBuilder_ == null) {
          ensureParsingErrorIsMutable();
          parsingError_.add(index, builderForValue.build());
          onChanged();
        } else {
          parsingErrorBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       *optional, used when providing location of error within a piece of text.
       * </pre>
       *
       * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
       */
      public Builder addAllParsingError(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.UserBitShared.ParsingError> values) {
        if (parsingErrorBuilder_ == null) {
          ensureParsingErrorIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, parsingError_);
          onChanged();
        } else {
          parsingErrorBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <pre>
       *optional, used when providing location of error within a piece of text.
       * </pre>
       *
       * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
       */
      public Builder clearParsingError() {
        if (parsingErrorBuilder_ == null) {
          parsingError_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000020);
          onChanged();
        } else {
          parsingErrorBuilder_.clear();
        }
        return this;
      }
      /**
       * <pre>
       *optional, used when providing location of error within a piece of text.
       * </pre>
       *
       * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
       */
      public Builder removeParsingError(int index) {
        if (parsingErrorBuilder_ == null) {
          ensureParsingErrorIsMutable();
          parsingError_.remove(index);
          onChanged();
        } else {
          parsingErrorBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <pre>
       *optional, used when providing location of error within a piece of text.
       * </pre>
       *
       * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.ParsingError.Builder getParsingErrorBuilder(
          int index) {
        return getParsingErrorFieldBuilder().getBuilder(index);
      }
      /**
       * <pre>
       *optional, used when providing location of error within a piece of text.
       * </pre>
       *
       * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.ParsingErrorOrBuilder getParsingErrorOrBuilder(
          int index) {
        if (parsingErrorBuilder_ == null) {
          return parsingError_.get(index);  } else {
          return parsingErrorBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <pre>
       *optional, used when providing location of error within a piece of text.
       * </pre>
       *
       * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
       */
      public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.ParsingErrorOrBuilder> 
           getParsingErrorOrBuilderList() {
        if (parsingErrorBuilder_ != null) {
          return parsingErrorBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(parsingError_);
        }
      }
      /**
       * <pre>
       *optional, used when providing location of error within a piece of text.
       * </pre>
       *
       * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.ParsingError.Builder addParsingErrorBuilder() {
        return getParsingErrorFieldBuilder().addBuilder(
            org.apache.drill.exec.proto.UserBitShared.ParsingError.getDefaultInstance());
      }
      /**
       * <pre>
       *optional, used when providing location of error within a piece of text.
       * </pre>
       *
       * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.ParsingError.Builder addParsingErrorBuilder(
          int index) {
        return getParsingErrorFieldBuilder().addBuilder(
            index, org.apache.drill.exec.proto.UserBitShared.ParsingError.getDefaultInstance());
      }
      /**
       * <pre>
       *optional, used when providing location of error within a piece of text.
       * </pre>
       *
       * <code>repeated .exec.shared.ParsingError parsing_error = 6;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserBitShared.ParsingError.Builder> 
           getParsingErrorBuilderList() {
        return getParsingErrorFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.ParsingError, org.apache.drill.exec.proto.UserBitShared.ParsingError.Builder, org.apache.drill.exec.proto.UserBitShared.ParsingErrorOrBuilder> 
          getParsingErrorFieldBuilder() {
        if (parsingErrorBuilder_ == null) {
          parsingErrorBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.ParsingError, org.apache.drill.exec.proto.UserBitShared.ParsingError.Builder, org.apache.drill.exec.proto.UserBitShared.ParsingErrorOrBuilder>(
                  parsingError_,
                  ((bitField0_ & 0x00000020) != 0),
                  getParentForChildren(),
                  isClean());
          parsingError_ = null;
        }
        return parsingErrorBuilder_;
      }
      @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:exec.shared.DrillPBError)
    }

    // @@protoc_insertion_point(class_scope:exec.shared.DrillPBError)
    private static final org.apache.drill.exec.proto.UserBitShared.DrillPBError DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserBitShared.DrillPBError();
    }

    public static org.apache.drill.exec.proto.UserBitShared.DrillPBError getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<DrillPBError>
        PARSER = new com.google.protobuf.AbstractParser<DrillPBError>() {
      @java.lang.Override
      public DrillPBError parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

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

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

    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.DrillPBError getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface ExceptionWrapperOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.shared.ExceptionWrapper)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional string exception_class = 1;</code>
     * @return Whether the exceptionClass field is set.
     */
    boolean hasExceptionClass();
    /**
     * <code>optional string exception_class = 1;</code>
     * @return The exceptionClass.
     */
    java.lang.String getExceptionClass();
    /**
     * <code>optional string exception_class = 1;</code>
     * @return The bytes for exceptionClass.
     */
    com.google.protobuf.ByteString
        getExceptionClassBytes();

    /**
     * <code>optional string message = 2;</code>
     * @return Whether the message field is set.
     */
    boolean hasMessage();
    /**
     * <code>optional string message = 2;</code>
     * @return The message.
     */
    java.lang.String getMessage();
    /**
     * <code>optional string message = 2;</code>
     * @return The bytes for message.
     */
    com.google.protobuf.ByteString
        getMessageBytes();

    /**
     * <code>repeated .exec.shared.StackTraceElementWrapper stack_trace = 3;</code>
     */
    java.util.List<org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper> 
        getStackTraceList();
    /**
     * <code>repeated .exec.shared.StackTraceElementWrapper stack_trace = 3;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper getStackTrace(int index);
    /**
     * <code>repeated .exec.shared.StackTraceElementWrapper stack_trace = 3;</code>
     */
    int getStackTraceCount();
    /**
     * <code>repeated .exec.shared.StackTraceElementWrapper stack_trace = 3;</code>
     */
    java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapperOrBuilder> 
        getStackTraceOrBuilderList();
    /**
     * <code>repeated .exec.shared.StackTraceElementWrapper stack_trace = 3;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapperOrBuilder getStackTraceOrBuilder(
        int index);

    /**
     * <code>optional .exec.shared.ExceptionWrapper cause = 4;</code>
     * @return Whether the cause field is set.
     */
    boolean hasCause();
    /**
     * <code>optional .exec.shared.ExceptionWrapper cause = 4;</code>
     * @return The cause.
     */
    org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper getCause();
    /**
     * <code>optional .exec.shared.ExceptionWrapper cause = 4;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.ExceptionWrapperOrBuilder getCauseOrBuilder();
  }
  /**
   * Protobuf type {@code exec.shared.ExceptionWrapper}
   */
  public static final class ExceptionWrapper extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.ExceptionWrapper)
      ExceptionWrapperOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use ExceptionWrapper.newBuilder() to construct.
    private ExceptionWrapper(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private ExceptionWrapper() {
      exceptionClass_ = "";
      message_ = "";
      stackTrace_ = java.util.Collections.emptyList();
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new ExceptionWrapper();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_ExceptionWrapper_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_ExceptionWrapper_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.class, org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.Builder.class);
    }

    private int bitField0_;
    public static final int EXCEPTION_CLASS_FIELD_NUMBER = 1;
    private volatile java.lang.Object exceptionClass_;
    /**
     * <code>optional string exception_class = 1;</code>
     * @return Whether the exceptionClass field is set.
     */
    @java.lang.Override
    public boolean hasExceptionClass() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional string exception_class = 1;</code>
     * @return The exceptionClass.
     */
    @java.lang.Override
    public java.lang.String getExceptionClass() {
      java.lang.Object ref = exceptionClass_;
      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();
        if (bs.isValidUtf8()) {
          exceptionClass_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string exception_class = 1;</code>
     * @return The bytes for exceptionClass.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getExceptionClassBytes() {
      java.lang.Object ref = exceptionClass_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        exceptionClass_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int MESSAGE_FIELD_NUMBER = 2;
    private volatile java.lang.Object message_;
    /**
     * <code>optional string message = 2;</code>
     * @return Whether the message field is set.
     */
    @java.lang.Override
    public boolean hasMessage() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional string message = 2;</code>
     * @return The message.
     */
    @java.lang.Override
    public java.lang.String getMessage() {
      java.lang.Object ref = message_;
      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();
        if (bs.isValidUtf8()) {
          message_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string message = 2;</code>
     * @return The bytes for message.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getMessageBytes() {
      java.lang.Object ref = message_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        message_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int STACK_TRACE_FIELD_NUMBER = 3;
    private java.util.List<org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper> stackTrace_;
    /**
     * <code>repeated .exec.shared.StackTraceElementWrapper stack_trace = 3;</code>
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper> getStackTraceList() {
      return stackTrace_;
    }
    /**
     * <code>repeated .exec.shared.StackTraceElementWrapper stack_trace = 3;</code>
     */
    @java.lang.Override
    public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapperOrBuilder> 
        getStackTraceOrBuilderList() {
      return stackTrace_;
    }
    /**
     * <code>repeated .exec.shared.StackTraceElementWrapper stack_trace = 3;</code>
     */
    @java.lang.Override
    public int getStackTraceCount() {
      return stackTrace_.size();
    }
    /**
     * <code>repeated .exec.shared.StackTraceElementWrapper stack_trace = 3;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper getStackTrace(int index) {
      return stackTrace_.get(index);
    }
    /**
     * <code>repeated .exec.shared.StackTraceElementWrapper stack_trace = 3;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapperOrBuilder getStackTraceOrBuilder(
        int index) {
      return stackTrace_.get(index);
    }

    public static final int CAUSE_FIELD_NUMBER = 4;
    private org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper cause_;
    /**
     * <code>optional .exec.shared.ExceptionWrapper cause = 4;</code>
     * @return Whether the cause field is set.
     */
    @java.lang.Override
    public boolean hasCause() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional .exec.shared.ExceptionWrapper cause = 4;</code>
     * @return The cause.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper getCause() {
      return cause_ == null ? org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.getDefaultInstance() : cause_;
    }
    /**
     * <code>optional .exec.shared.ExceptionWrapper cause = 4;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.ExceptionWrapperOrBuilder getCauseOrBuilder() {
      return cause_ == null ? org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.getDefaultInstance() : cause_;
    }

    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 (((bitField0_ & 0x00000001) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, exceptionClass_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, message_);
      }
      for (int i = 0; i < stackTrace_.size(); i++) {
        output.writeMessage(3, stackTrace_.get(i));
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeMessage(4, getCause());
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, exceptionClass_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, message_);
      }
      for (int i = 0; i < stackTrace_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, stackTrace_.get(i));
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(4, getCause());
      }
      size += getUnknownFields().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.drill.exec.proto.UserBitShared.ExceptionWrapper)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper other = (org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper) obj;

      if (hasExceptionClass() != other.hasExceptionClass()) return false;
      if (hasExceptionClass()) {
        if (!getExceptionClass()
            .equals(other.getExceptionClass())) return false;
      }
      if (hasMessage() != other.hasMessage()) return false;
      if (hasMessage()) {
        if (!getMessage()
            .equals(other.getMessage())) return false;
      }
      if (!getStackTraceList()
          .equals(other.getStackTraceList())) return false;
      if (hasCause() != other.hasCause()) return false;
      if (hasCause()) {
        if (!getCause()
            .equals(other.getCause())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasExceptionClass()) {
        hash = (37 * hash) + EXCEPTION_CLASS_FIELD_NUMBER;
        hash = (53 * hash) + getExceptionClass().hashCode();
      }
      if (hasMessage()) {
        hash = (37 * hash) + MESSAGE_FIELD_NUMBER;
        hash = (53 * hash) + getMessage().hashCode();
      }
      if (getStackTraceCount() > 0) {
        hash = (37 * hash) + STACK_TRACE_FIELD_NUMBER;
        hash = (53 * hash) + getStackTraceList().hashCode();
      }
      if (hasCause()) {
        hash = (37 * hash) + CAUSE_FIELD_NUMBER;
        hash = (53 * hash) + getCause().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper 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.drill.exec.proto.UserBitShared.ExceptionWrapper parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper 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.drill.exec.proto.UserBitShared.ExceptionWrapper parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper 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.drill.exec.proto.UserBitShared.ExceptionWrapper parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper 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.drill.exec.proto.UserBitShared.ExceptionWrapper 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 exec.shared.ExceptionWrapper}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.shared.ExceptionWrapper)
        org.apache.drill.exec.proto.UserBitShared.ExceptionWrapperOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_ExceptionWrapper_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_ExceptionWrapper_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.class, org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getStackTraceFieldBuilder();
          getCauseFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        exceptionClass_ = "";
        bitField0_ = (bitField0_ & ~0x00000001);
        message_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        if (stackTraceBuilder_ == null) {
          stackTrace_ = java.util.Collections.emptyList();
        } else {
          stackTrace_ = null;
          stackTraceBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        if (causeBuilder_ == null) {
          cause_ = null;
        } else {
          causeBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_ExceptionWrapper_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper build() {
        org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper buildPartial() {
        org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper result = new org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.exceptionClass_ = exceptionClass_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          to_bitField0_ |= 0x00000002;
        }
        result.message_ = message_;
        if (stackTraceBuilder_ == null) {
          if (((bitField0_ & 0x00000004) != 0)) {
            stackTrace_ = java.util.Collections.unmodifiableList(stackTrace_);
            bitField0_ = (bitField0_ & ~0x00000004);
          }
          result.stackTrace_ = stackTrace_;
        } else {
          result.stackTrace_ = stackTraceBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000008) != 0)) {
          if (causeBuilder_ == null) {
            result.cause_ = cause_;
          } else {
            result.cause_ = causeBuilder_.build();
          }
          to_bitField0_ |= 0x00000004;
        }
        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.drill.exec.proto.UserBitShared.ExceptionWrapper) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.getDefaultInstance()) return this;
        if (other.hasExceptionClass()) {
          bitField0_ |= 0x00000001;
          exceptionClass_ = other.exceptionClass_;
          onChanged();
        }
        if (other.hasMessage()) {
          bitField0_ |= 0x00000002;
          message_ = other.message_;
          onChanged();
        }
        if (stackTraceBuilder_ == null) {
          if (!other.stackTrace_.isEmpty()) {
            if (stackTrace_.isEmpty()) {
              stackTrace_ = other.stackTrace_;
              bitField0_ = (bitField0_ & ~0x00000004);
            } else {
              ensureStackTraceIsMutable();
              stackTrace_.addAll(other.stackTrace_);
            }
            onChanged();
          }
        } else {
          if (!other.stackTrace_.isEmpty()) {
            if (stackTraceBuilder_.isEmpty()) {
              stackTraceBuilder_.dispose();
              stackTraceBuilder_ = null;
              stackTrace_ = other.stackTrace_;
              bitField0_ = (bitField0_ & ~0x00000004);
              stackTraceBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getStackTraceFieldBuilder() : null;
            } else {
              stackTraceBuilder_.addAllMessages(other.stackTrace_);
            }
          }
        }
        if (other.hasCause()) {
          mergeCause(other.getCause());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        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 {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                exceptionClass_ = input.readBytes();
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 18: {
                message_ = input.readBytes();
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              case 26: {
                org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper m =
                    input.readMessage(
                        org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper.PARSER,
                        extensionRegistry);
                if (stackTraceBuilder_ == null) {
                  ensureStackTraceIsMutable();
                  stackTrace_.add(m);
                } else {
                  stackTraceBuilder_.addMessage(m);
                }
                break;
              } // case 26
              case 34: {
                input.readMessage(
                    getCauseFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000008;
                break;
              } // case 34
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.lang.Object exceptionClass_ = "";
      /**
       * <code>optional string exception_class = 1;</code>
       * @return Whether the exceptionClass field is set.
       */
      public boolean hasExceptionClass() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional string exception_class = 1;</code>
       * @return The exceptionClass.
       */
      public java.lang.String getExceptionClass() {
        java.lang.Object ref = exceptionClass_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            exceptionClass_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string exception_class = 1;</code>
       * @return The bytes for exceptionClass.
       */
      public com.google.protobuf.ByteString
          getExceptionClassBytes() {
        java.lang.Object ref = exceptionClass_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          exceptionClass_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string exception_class = 1;</code>
       * @param value The exceptionClass to set.
       * @return This builder for chaining.
       */
      public Builder setExceptionClass(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        exceptionClass_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception_class = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearExceptionClass() {
        bitField0_ = (bitField0_ & ~0x00000001);
        exceptionClass_ = getDefaultInstance().getExceptionClass();
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception_class = 1;</code>
       * @param value The bytes for exceptionClass to set.
       * @return This builder for chaining.
       */
      public Builder setExceptionClassBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        exceptionClass_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object message_ = "";
      /**
       * <code>optional string message = 2;</code>
       * @return Whether the message field is set.
       */
      public boolean hasMessage() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional string message = 2;</code>
       * @return The message.
       */
      public java.lang.String getMessage() {
        java.lang.Object ref = message_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            message_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string message = 2;</code>
       * @return The bytes for message.
       */
      public com.google.protobuf.ByteString
          getMessageBytes() {
        java.lang.Object ref = message_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          message_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string message = 2;</code>
       * @param value The message to set.
       * @return This builder for chaining.
       */
      public Builder setMessage(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        message_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string message = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearMessage() {
        bitField0_ = (bitField0_ & ~0x00000002);
        message_ = getDefaultInstance().getMessage();
        onChanged();
        return this;
      }
      /**
       * <code>optional string message = 2;</code>
       * @param value The bytes for message to set.
       * @return This builder for chaining.
       */
      public Builder setMessageBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        message_ = value;
        onChanged();
        return this;
      }

      private java.util.List<org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper> stackTrace_ =
        java.util.Collections.emptyList();
      private void ensureStackTraceIsMutable() {
        if (!((bitField0_ & 0x00000004) != 0)) {
          stackTrace_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper>(stackTrace_);
          bitField0_ |= 0x00000004;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper, org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper.Builder, org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapperOrBuilder> stackTraceBuilder_;

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

      private org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper cause_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper, org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.Builder, org.apache.drill.exec.proto.UserBitShared.ExceptionWrapperOrBuilder> causeBuilder_;
      /**
       * <code>optional .exec.shared.ExceptionWrapper cause = 4;</code>
       * @return Whether the cause field is set.
       */
      public boolean hasCause() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <code>optional .exec.shared.ExceptionWrapper cause = 4;</code>
       * @return The cause.
       */
      public org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper getCause() {
        if (causeBuilder_ == null) {
          return cause_ == null ? org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.getDefaultInstance() : cause_;
        } else {
          return causeBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.shared.ExceptionWrapper cause = 4;</code>
       */
      public Builder setCause(org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper value) {
        if (causeBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          cause_ = value;
          onChanged();
        } else {
          causeBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .exec.shared.ExceptionWrapper cause = 4;</code>
       */
      public Builder setCause(
          org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.Builder builderForValue) {
        if (causeBuilder_ == null) {
          cause_ = builderForValue.build();
          onChanged();
        } else {
          causeBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .exec.shared.ExceptionWrapper cause = 4;</code>
       */
      public Builder mergeCause(org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper value) {
        if (causeBuilder_ == null) {
          if (((bitField0_ & 0x00000008) != 0) &&
              cause_ != null &&
              cause_ != org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.getDefaultInstance()) {
            cause_ =
              org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.newBuilder(cause_).mergeFrom(value).buildPartial();
          } else {
            cause_ = value;
          }
          onChanged();
        } else {
          causeBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .exec.shared.ExceptionWrapper cause = 4;</code>
       */
      public Builder clearCause() {
        if (causeBuilder_ == null) {
          cause_ = null;
          onChanged();
        } else {
          causeBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }
      /**
       * <code>optional .exec.shared.ExceptionWrapper cause = 4;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.Builder getCauseBuilder() {
        bitField0_ |= 0x00000008;
        onChanged();
        return getCauseFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.shared.ExceptionWrapper cause = 4;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.ExceptionWrapperOrBuilder getCauseOrBuilder() {
        if (causeBuilder_ != null) {
          return causeBuilder_.getMessageOrBuilder();
        } else {
          return cause_ == null ?
              org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.getDefaultInstance() : cause_;
        }
      }
      /**
       * <code>optional .exec.shared.ExceptionWrapper cause = 4;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper, org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.Builder, org.apache.drill.exec.proto.UserBitShared.ExceptionWrapperOrBuilder> 
          getCauseFieldBuilder() {
        if (causeBuilder_ == null) {
          causeBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper, org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.Builder, org.apache.drill.exec.proto.UserBitShared.ExceptionWrapperOrBuilder>(
                  getCause(),
                  getParentForChildren(),
                  isClean());
          cause_ = null;
        }
        return causeBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

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


      // @@protoc_insertion_point(builder_scope:exec.shared.ExceptionWrapper)
    }

    // @@protoc_insertion_point(class_scope:exec.shared.ExceptionWrapper)
    private static final org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper();
    }

    public static org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<ExceptionWrapper>
        PARSER = new com.google.protobuf.AbstractParser<ExceptionWrapper>() {
      @java.lang.Override
      public ExceptionWrapper parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

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

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

    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface StackTraceElementWrapperOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.shared.StackTraceElementWrapper)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional string class_name = 1;</code>
     * @return Whether the className field is set.
     */
    boolean hasClassName();
    /**
     * <code>optional string class_name = 1;</code>
     * @return The className.
     */
    java.lang.String getClassName();
    /**
     * <code>optional string class_name = 1;</code>
     * @return The bytes for className.
     */
    com.google.protobuf.ByteString
        getClassNameBytes();

    /**
     * <code>optional string file_name = 2;</code>
     * @return Whether the fileName field is set.
     */
    boolean hasFileName();
    /**
     * <code>optional string file_name = 2;</code>
     * @return The fileName.
     */
    java.lang.String getFileName();
    /**
     * <code>optional string file_name = 2;</code>
     * @return The bytes for fileName.
     */
    com.google.protobuf.ByteString
        getFileNameBytes();

    /**
     * <code>optional int32 line_number = 3;</code>
     * @return Whether the lineNumber field is set.
     */
    boolean hasLineNumber();
    /**
     * <code>optional int32 line_number = 3;</code>
     * @return The lineNumber.
     */
    int getLineNumber();

    /**
     * <code>optional string method_name = 4;</code>
     * @return Whether the methodName field is set.
     */
    boolean hasMethodName();
    /**
     * <code>optional string method_name = 4;</code>
     * @return The methodName.
     */
    java.lang.String getMethodName();
    /**
     * <code>optional string method_name = 4;</code>
     * @return The bytes for methodName.
     */
    com.google.protobuf.ByteString
        getMethodNameBytes();

    /**
     * <code>optional bool is_native_method = 5;</code>
     * @return Whether the isNativeMethod field is set.
     */
    boolean hasIsNativeMethod();
    /**
     * <code>optional bool is_native_method = 5;</code>
     * @return The isNativeMethod.
     */
    boolean getIsNativeMethod();
  }
  /**
   * Protobuf type {@code exec.shared.StackTraceElementWrapper}
   */
  public static final class StackTraceElementWrapper extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.StackTraceElementWrapper)
      StackTraceElementWrapperOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use StackTraceElementWrapper.newBuilder() to construct.
    private StackTraceElementWrapper(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private StackTraceElementWrapper() {
      className_ = "";
      fileName_ = "";
      methodName_ = "";
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new StackTraceElementWrapper();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_StackTraceElementWrapper_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_StackTraceElementWrapper_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper.class, org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper.Builder.class);
    }

    private int bitField0_;
    public static final int CLASS_NAME_FIELD_NUMBER = 1;
    private volatile java.lang.Object className_;
    /**
     * <code>optional string class_name = 1;</code>
     * @return Whether the className field is set.
     */
    @java.lang.Override
    public boolean hasClassName() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional string class_name = 1;</code>
     * @return The className.
     */
    @java.lang.Override
    public java.lang.String getClassName() {
      java.lang.Object ref = className_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          className_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string class_name = 1;</code>
     * @return The bytes for className.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getClassNameBytes() {
      java.lang.Object ref = className_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        className_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int FILE_NAME_FIELD_NUMBER = 2;
    private volatile java.lang.Object fileName_;
    /**
     * <code>optional string file_name = 2;</code>
     * @return Whether the fileName field is set.
     */
    @java.lang.Override
    public boolean hasFileName() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional string file_name = 2;</code>
     * @return The fileName.
     */
    @java.lang.Override
    public java.lang.String getFileName() {
      java.lang.Object ref = fileName_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          fileName_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string file_name = 2;</code>
     * @return The bytes for fileName.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getFileNameBytes() {
      java.lang.Object ref = fileName_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        fileName_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int LINE_NUMBER_FIELD_NUMBER = 3;
    private int lineNumber_;
    /**
     * <code>optional int32 line_number = 3;</code>
     * @return Whether the lineNumber field is set.
     */
    @java.lang.Override
    public boolean hasLineNumber() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional int32 line_number = 3;</code>
     * @return The lineNumber.
     */
    @java.lang.Override
    public int getLineNumber() {
      return lineNumber_;
    }

    public static final int METHOD_NAME_FIELD_NUMBER = 4;
    private volatile java.lang.Object methodName_;
    /**
     * <code>optional string method_name = 4;</code>
     * @return Whether the methodName field is set.
     */
    @java.lang.Override
    public boolean hasMethodName() {
      return ((bitField0_ & 0x00000008) != 0);
    }
    /**
     * <code>optional string method_name = 4;</code>
     * @return The methodName.
     */
    @java.lang.Override
    public java.lang.String getMethodName() {
      java.lang.Object ref = methodName_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          methodName_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string method_name = 4;</code>
     * @return The bytes for methodName.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getMethodNameBytes() {
      java.lang.Object ref = methodName_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        methodName_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int IS_NATIVE_METHOD_FIELD_NUMBER = 5;
    private boolean isNativeMethod_;
    /**
     * <code>optional bool is_native_method = 5;</code>
     * @return Whether the isNativeMethod field is set.
     */
    @java.lang.Override
    public boolean hasIsNativeMethod() {
      return ((bitField0_ & 0x00000010) != 0);
    }
    /**
     * <code>optional bool is_native_method = 5;</code>
     * @return The isNativeMethod.
     */
    @java.lang.Override
    public boolean getIsNativeMethod() {
      return isNativeMethod_;
    }

    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 (((bitField0_ & 0x00000001) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, className_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, fileName_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeInt32(3, lineNumber_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 4, methodName_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        output.writeBool(5, isNativeMethod_);
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, className_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, fileName_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(3, lineNumber_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, methodName_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(5, isNativeMethod_);
      }
      size += getUnknownFields().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.drill.exec.proto.UserBitShared.StackTraceElementWrapper)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper other = (org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper) obj;

      if (hasClassName() != other.hasClassName()) return false;
      if (hasClassName()) {
        if (!getClassName()
            .equals(other.getClassName())) return false;
      }
      if (hasFileName() != other.hasFileName()) return false;
      if (hasFileName()) {
        if (!getFileName()
            .equals(other.getFileName())) return false;
      }
      if (hasLineNumber() != other.hasLineNumber()) return false;
      if (hasLineNumber()) {
        if (getLineNumber()
            != other.getLineNumber()) return false;
      }
      if (hasMethodName() != other.hasMethodName()) return false;
      if (hasMethodName()) {
        if (!getMethodName()
            .equals(other.getMethodName())) return false;
      }
      if (hasIsNativeMethod() != other.hasIsNativeMethod()) return false;
      if (hasIsNativeMethod()) {
        if (getIsNativeMethod()
            != other.getIsNativeMethod()) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasClassName()) {
        hash = (37 * hash) + CLASS_NAME_FIELD_NUMBER;
        hash = (53 * hash) + getClassName().hashCode();
      }
      if (hasFileName()) {
        hash = (37 * hash) + FILE_NAME_FIELD_NUMBER;
        hash = (53 * hash) + getFileName().hashCode();
      }
      if (hasLineNumber()) {
        hash = (37 * hash) + LINE_NUMBER_FIELD_NUMBER;
        hash = (53 * hash) + getLineNumber();
      }
      if (hasMethodName()) {
        hash = (37 * hash) + METHOD_NAME_FIELD_NUMBER;
        hash = (53 * hash) + getMethodName().hashCode();
      }
      if (hasIsNativeMethod()) {
        hash = (37 * hash) + IS_NATIVE_METHOD_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getIsNativeMethod());
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper 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.drill.exec.proto.UserBitShared.StackTraceElementWrapper parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper 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.drill.exec.proto.UserBitShared.StackTraceElementWrapper parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper 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.drill.exec.proto.UserBitShared.StackTraceElementWrapper parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper 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.drill.exec.proto.UserBitShared.StackTraceElementWrapper 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 exec.shared.StackTraceElementWrapper}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.shared.StackTraceElementWrapper)
        org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapperOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_StackTraceElementWrapper_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_StackTraceElementWrapper_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper.class, org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        className_ = "";
        bitField0_ = (bitField0_ & ~0x00000001);
        fileName_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        lineNumber_ = 0;
        bitField0_ = (bitField0_ & ~0x00000004);
        methodName_ = "";
        bitField0_ = (bitField0_ & ~0x00000008);
        isNativeMethod_ = false;
        bitField0_ = (bitField0_ & ~0x00000010);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_StackTraceElementWrapper_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper build() {
        org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper buildPartial() {
        org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper result = new org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.className_ = className_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          to_bitField0_ |= 0x00000002;
        }
        result.fileName_ = fileName_;
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.lineNumber_ = lineNumber_;
          to_bitField0_ |= 0x00000004;
        }
        if (((from_bitField0_ & 0x00000008) != 0)) {
          to_bitField0_ |= 0x00000008;
        }
        result.methodName_ = methodName_;
        if (((from_bitField0_ & 0x00000010) != 0)) {
          result.isNativeMethod_ = isNativeMethod_;
          to_bitField0_ |= 0x00000010;
        }
        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.drill.exec.proto.UserBitShared.StackTraceElementWrapper) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper.getDefaultInstance()) return this;
        if (other.hasClassName()) {
          bitField0_ |= 0x00000001;
          className_ = other.className_;
          onChanged();
        }
        if (other.hasFileName()) {
          bitField0_ |= 0x00000002;
          fileName_ = other.fileName_;
          onChanged();
        }
        if (other.hasLineNumber()) {
          setLineNumber(other.getLineNumber());
        }
        if (other.hasMethodName()) {
          bitField0_ |= 0x00000008;
          methodName_ = other.methodName_;
          onChanged();
        }
        if (other.hasIsNativeMethod()) {
          setIsNativeMethod(other.getIsNativeMethod());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        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 {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                className_ = input.readBytes();
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 18: {
                fileName_ = input.readBytes();
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              case 24: {
                lineNumber_ = input.readInt32();
                bitField0_ |= 0x00000004;
                break;
              } // case 24
              case 34: {
                methodName_ = input.readBytes();
                bitField0_ |= 0x00000008;
                break;
              } // case 34
              case 40: {
                isNativeMethod_ = input.readBool();
                bitField0_ |= 0x00000010;
                break;
              } // case 40
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.lang.Object className_ = "";
      /**
       * <code>optional string class_name = 1;</code>
       * @return Whether the className field is set.
       */
      public boolean hasClassName() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional string class_name = 1;</code>
       * @return The className.
       */
      public java.lang.String getClassName() {
        java.lang.Object ref = className_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            className_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string class_name = 1;</code>
       * @return The bytes for className.
       */
      public com.google.protobuf.ByteString
          getClassNameBytes() {
        java.lang.Object ref = className_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          className_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string class_name = 1;</code>
       * @param value The className to set.
       * @return This builder for chaining.
       */
      public Builder setClassName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        className_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string class_name = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearClassName() {
        bitField0_ = (bitField0_ & ~0x00000001);
        className_ = getDefaultInstance().getClassName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string class_name = 1;</code>
       * @param value The bytes for className to set.
       * @return This builder for chaining.
       */
      public Builder setClassNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        className_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object fileName_ = "";
      /**
       * <code>optional string file_name = 2;</code>
       * @return Whether the fileName field is set.
       */
      public boolean hasFileName() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional string file_name = 2;</code>
       * @return The fileName.
       */
      public java.lang.String getFileName() {
        java.lang.Object ref = fileName_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            fileName_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string file_name = 2;</code>
       * @return The bytes for fileName.
       */
      public com.google.protobuf.ByteString
          getFileNameBytes() {
        java.lang.Object ref = fileName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          fileName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string file_name = 2;</code>
       * @param value The fileName to set.
       * @return This builder for chaining.
       */
      public Builder setFileName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        fileName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string file_name = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearFileName() {
        bitField0_ = (bitField0_ & ~0x00000002);
        fileName_ = getDefaultInstance().getFileName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string file_name = 2;</code>
       * @param value The bytes for fileName to set.
       * @return This builder for chaining.
       */
      public Builder setFileNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        fileName_ = value;
        onChanged();
        return this;
      }

      private int lineNumber_ ;
      /**
       * <code>optional int32 line_number = 3;</code>
       * @return Whether the lineNumber field is set.
       */
      @java.lang.Override
      public boolean hasLineNumber() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional int32 line_number = 3;</code>
       * @return The lineNumber.
       */
      @java.lang.Override
      public int getLineNumber() {
        return lineNumber_;
      }
      /**
       * <code>optional int32 line_number = 3;</code>
       * @param value The lineNumber to set.
       * @return This builder for chaining.
       */
      public Builder setLineNumber(int value) {
        bitField0_ |= 0x00000004;
        lineNumber_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 line_number = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearLineNumber() {
        bitField0_ = (bitField0_ & ~0x00000004);
        lineNumber_ = 0;
        onChanged();
        return this;
      }

      private java.lang.Object methodName_ = "";
      /**
       * <code>optional string method_name = 4;</code>
       * @return Whether the methodName field is set.
       */
      public boolean hasMethodName() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <code>optional string method_name = 4;</code>
       * @return The methodName.
       */
      public java.lang.String getMethodName() {
        java.lang.Object ref = methodName_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            methodName_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string method_name = 4;</code>
       * @return The bytes for methodName.
       */
      public com.google.protobuf.ByteString
          getMethodNameBytes() {
        java.lang.Object ref = methodName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          methodName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string method_name = 4;</code>
       * @param value The methodName to set.
       * @return This builder for chaining.
       */
      public Builder setMethodName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        methodName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string method_name = 4;</code>
       * @return This builder for chaining.
       */
      public Builder clearMethodName() {
        bitField0_ = (bitField0_ & ~0x00000008);
        methodName_ = getDefaultInstance().getMethodName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string method_name = 4;</code>
       * @param value The bytes for methodName to set.
       * @return This builder for chaining.
       */
      public Builder setMethodNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        methodName_ = value;
        onChanged();
        return this;
      }

      private boolean isNativeMethod_ ;
      /**
       * <code>optional bool is_native_method = 5;</code>
       * @return Whether the isNativeMethod field is set.
       */
      @java.lang.Override
      public boolean hasIsNativeMethod() {
        return ((bitField0_ & 0x00000010) != 0);
      }
      /**
       * <code>optional bool is_native_method = 5;</code>
       * @return The isNativeMethod.
       */
      @java.lang.Override
      public boolean getIsNativeMethod() {
        return isNativeMethod_;
      }
      /**
       * <code>optional bool is_native_method = 5;</code>
       * @param value The isNativeMethod to set.
       * @return This builder for chaining.
       */
      public Builder setIsNativeMethod(boolean value) {
        bitField0_ |= 0x00000010;
        isNativeMethod_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool is_native_method = 5;</code>
       * @return This builder for chaining.
       */
      public Builder clearIsNativeMethod() {
        bitField0_ = (bitField0_ & ~0x00000010);
        isNativeMethod_ = false;
        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:exec.shared.StackTraceElementWrapper)
    }

    // @@protoc_insertion_point(class_scope:exec.shared.StackTraceElementWrapper)
    private static final org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper();
    }

    public static org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<StackTraceElementWrapper>
        PARSER = new com.google.protobuf.AbstractParser<StackTraceElementWrapper>() {
      @java.lang.Override
      public StackTraceElementWrapper parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

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

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

    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface ParsingErrorOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.shared.ParsingError)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional int32 start_column = 2;</code>
     * @return Whether the startColumn field is set.
     */
    boolean hasStartColumn();
    /**
     * <code>optional int32 start_column = 2;</code>
     * @return The startColumn.
     */
    int getStartColumn();

    /**
     * <code>optional int32 start_row = 3;</code>
     * @return Whether the startRow field is set.
     */
    boolean hasStartRow();
    /**
     * <code>optional int32 start_row = 3;</code>
     * @return The startRow.
     */
    int getStartRow();

    /**
     * <code>optional int32 end_column = 4;</code>
     * @return Whether the endColumn field is set.
     */
    boolean hasEndColumn();
    /**
     * <code>optional int32 end_column = 4;</code>
     * @return The endColumn.
     */
    int getEndColumn();

    /**
     * <code>optional int32 end_row = 5;</code>
     * @return Whether the endRow field is set.
     */
    boolean hasEndRow();
    /**
     * <code>optional int32 end_row = 5;</code>
     * @return The endRow.
     */
    int getEndRow();
  }
  /**
   * Protobuf type {@code exec.shared.ParsingError}
   */
  public static final class ParsingError extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.ParsingError)
      ParsingErrorOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use ParsingError.newBuilder() to construct.
    private ParsingError(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private ParsingError() {
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new ParsingError();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_ParsingError_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_ParsingError_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserBitShared.ParsingError.class, org.apache.drill.exec.proto.UserBitShared.ParsingError.Builder.class);
    }

    private int bitField0_;
    public static final int START_COLUMN_FIELD_NUMBER = 2;
    private int startColumn_;
    /**
     * <code>optional int32 start_column = 2;</code>
     * @return Whether the startColumn field is set.
     */
    @java.lang.Override
    public boolean hasStartColumn() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional int32 start_column = 2;</code>
     * @return The startColumn.
     */
    @java.lang.Override
    public int getStartColumn() {
      return startColumn_;
    }

    public static final int START_ROW_FIELD_NUMBER = 3;
    private int startRow_;
    /**
     * <code>optional int32 start_row = 3;</code>
     * @return Whether the startRow field is set.
     */
    @java.lang.Override
    public boolean hasStartRow() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional int32 start_row = 3;</code>
     * @return The startRow.
     */
    @java.lang.Override
    public int getStartRow() {
      return startRow_;
    }

    public static final int END_COLUMN_FIELD_NUMBER = 4;
    private int endColumn_;
    /**
     * <code>optional int32 end_column = 4;</code>
     * @return Whether the endColumn field is set.
     */
    @java.lang.Override
    public boolean hasEndColumn() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional int32 end_column = 4;</code>
     * @return The endColumn.
     */
    @java.lang.Override
    public int getEndColumn() {
      return endColumn_;
    }

    public static final int END_ROW_FIELD_NUMBER = 5;
    private int endRow_;
    /**
     * <code>optional int32 end_row = 5;</code>
     * @return Whether the endRow field is set.
     */
    @java.lang.Override
    public boolean hasEndRow() {
      return ((bitField0_ & 0x00000008) != 0);
    }
    /**
     * <code>optional int32 end_row = 5;</code>
     * @return The endRow.
     */
    @java.lang.Override
    public int getEndRow() {
      return endRow_;
    }

    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 (((bitField0_ & 0x00000001) != 0)) {
        output.writeInt32(2, startColumn_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeInt32(3, startRow_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeInt32(4, endColumn_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        output.writeInt32(5, endRow_);
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(2, startColumn_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(3, startRow_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(4, endColumn_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(5, endRow_);
      }
      size += getUnknownFields().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.drill.exec.proto.UserBitShared.ParsingError)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserBitShared.ParsingError other = (org.apache.drill.exec.proto.UserBitShared.ParsingError) obj;

      if (hasStartColumn() != other.hasStartColumn()) return false;
      if (hasStartColumn()) {
        if (getStartColumn()
            != other.getStartColumn()) return false;
      }
      if (hasStartRow() != other.hasStartRow()) return false;
      if (hasStartRow()) {
        if (getStartRow()
            != other.getStartRow()) return false;
      }
      if (hasEndColumn() != other.hasEndColumn()) return false;
      if (hasEndColumn()) {
        if (getEndColumn()
            != other.getEndColumn()) return false;
      }
      if (hasEndRow() != other.hasEndRow()) return false;
      if (hasEndRow()) {
        if (getEndRow()
            != other.getEndRow()) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasStartColumn()) {
        hash = (37 * hash) + START_COLUMN_FIELD_NUMBER;
        hash = (53 * hash) + getStartColumn();
      }
      if (hasStartRow()) {
        hash = (37 * hash) + START_ROW_FIELD_NUMBER;
        hash = (53 * hash) + getStartRow();
      }
      if (hasEndColumn()) {
        hash = (37 * hash) + END_COLUMN_FIELD_NUMBER;
        hash = (53 * hash) + getEndColumn();
      }
      if (hasEndRow()) {
        hash = (37 * hash) + END_ROW_FIELD_NUMBER;
        hash = (53 * hash) + getEndRow();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserBitShared.ParsingError parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.ParsingError parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.ParsingError parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.ParsingError 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.drill.exec.proto.UserBitShared.ParsingError parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.ParsingError parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.ParsingError parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.ParsingError 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.drill.exec.proto.UserBitShared.ParsingError parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.ParsingError 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.drill.exec.proto.UserBitShared.ParsingError parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.ParsingError 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.drill.exec.proto.UserBitShared.ParsingError 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 exec.shared.ParsingError}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.shared.ParsingError)
        org.apache.drill.exec.proto.UserBitShared.ParsingErrorOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_ParsingError_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_ParsingError_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserBitShared.ParsingError.class, org.apache.drill.exec.proto.UserBitShared.ParsingError.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserBitShared.ParsingError.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        startColumn_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        startRow_ = 0;
        bitField0_ = (bitField0_ & ~0x00000002);
        endColumn_ = 0;
        bitField0_ = (bitField0_ & ~0x00000004);
        endRow_ = 0;
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_ParsingError_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.ParsingError getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserBitShared.ParsingError.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.ParsingError build() {
        org.apache.drill.exec.proto.UserBitShared.ParsingError result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.ParsingError buildPartial() {
        org.apache.drill.exec.proto.UserBitShared.ParsingError result = new org.apache.drill.exec.proto.UserBitShared.ParsingError(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.startColumn_ = startColumn_;
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.startRow_ = startRow_;
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.endColumn_ = endColumn_;
          to_bitField0_ |= 0x00000004;
        }
        if (((from_bitField0_ & 0x00000008) != 0)) {
          result.endRow_ = endRow_;
          to_bitField0_ |= 0x00000008;
        }
        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.drill.exec.proto.UserBitShared.ParsingError) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.ParsingError)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.ParsingError other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.ParsingError.getDefaultInstance()) return this;
        if (other.hasStartColumn()) {
          setStartColumn(other.getStartColumn());
        }
        if (other.hasStartRow()) {
          setStartRow(other.getStartRow());
        }
        if (other.hasEndColumn()) {
          setEndColumn(other.getEndColumn());
        }
        if (other.hasEndRow()) {
          setEndRow(other.getEndRow());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        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 {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 16: {
                startColumn_ = input.readInt32();
                bitField0_ |= 0x00000001;
                break;
              } // case 16
              case 24: {
                startRow_ = input.readInt32();
                bitField0_ |= 0x00000002;
                break;
              } // case 24
              case 32: {
                endColumn_ = input.readInt32();
                bitField0_ |= 0x00000004;
                break;
              } // case 32
              case 40: {
                endRow_ = input.readInt32();
                bitField0_ |= 0x00000008;
                break;
              } // case 40
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private int startColumn_ ;
      /**
       * <code>optional int32 start_column = 2;</code>
       * @return Whether the startColumn field is set.
       */
      @java.lang.Override
      public boolean hasStartColumn() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional int32 start_column = 2;</code>
       * @return The startColumn.
       */
      @java.lang.Override
      public int getStartColumn() {
        return startColumn_;
      }
      /**
       * <code>optional int32 start_column = 2;</code>
       * @param value The startColumn to set.
       * @return This builder for chaining.
       */
      public Builder setStartColumn(int value) {
        bitField0_ |= 0x00000001;
        startColumn_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 start_column = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearStartColumn() {
        bitField0_ = (bitField0_ & ~0x00000001);
        startColumn_ = 0;
        onChanged();
        return this;
      }

      private int startRow_ ;
      /**
       * <code>optional int32 start_row = 3;</code>
       * @return Whether the startRow field is set.
       */
      @java.lang.Override
      public boolean hasStartRow() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional int32 start_row = 3;</code>
       * @return The startRow.
       */
      @java.lang.Override
      public int getStartRow() {
        return startRow_;
      }
      /**
       * <code>optional int32 start_row = 3;</code>
       * @param value The startRow to set.
       * @return This builder for chaining.
       */
      public Builder setStartRow(int value) {
        bitField0_ |= 0x00000002;
        startRow_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 start_row = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearStartRow() {
        bitField0_ = (bitField0_ & ~0x00000002);
        startRow_ = 0;
        onChanged();
        return this;
      }

      private int endColumn_ ;
      /**
       * <code>optional int32 end_column = 4;</code>
       * @return Whether the endColumn field is set.
       */
      @java.lang.Override
      public boolean hasEndColumn() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional int32 end_column = 4;</code>
       * @return The endColumn.
       */
      @java.lang.Override
      public int getEndColumn() {
        return endColumn_;
      }
      /**
       * <code>optional int32 end_column = 4;</code>
       * @param value The endColumn to set.
       * @return This builder for chaining.
       */
      public Builder setEndColumn(int value) {
        bitField0_ |= 0x00000004;
        endColumn_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 end_column = 4;</code>
       * @return This builder for chaining.
       */
      public Builder clearEndColumn() {
        bitField0_ = (bitField0_ & ~0x00000004);
        endColumn_ = 0;
        onChanged();
        return this;
      }

      private int endRow_ ;
      /**
       * <code>optional int32 end_row = 5;</code>
       * @return Whether the endRow field is set.
       */
      @java.lang.Override
      public boolean hasEndRow() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <code>optional int32 end_row = 5;</code>
       * @return The endRow.
       */
      @java.lang.Override
      public int getEndRow() {
        return endRow_;
      }
      /**
       * <code>optional int32 end_row = 5;</code>
       * @param value The endRow to set.
       * @return This builder for chaining.
       */
      public Builder setEndRow(int value) {
        bitField0_ |= 0x00000008;
        endRow_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 end_row = 5;</code>
       * @return This builder for chaining.
       */
      public Builder clearEndRow() {
        bitField0_ = (bitField0_ & ~0x00000008);
        endRow_ = 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:exec.shared.ParsingError)
    }

    // @@protoc_insertion_point(class_scope:exec.shared.ParsingError)
    private static final org.apache.drill.exec.proto.UserBitShared.ParsingError DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserBitShared.ParsingError();
    }

    public static org.apache.drill.exec.proto.UserBitShared.ParsingError getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<ParsingError>
        PARSER = new com.google.protobuf.AbstractParser<ParsingError>() {
      @java.lang.Override
      public ParsingError parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

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

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

    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.ParsingError getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface RecordBatchDefOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.shared.RecordBatchDef)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional int32 record_count = 1;</code>
     * @return Whether the recordCount field is set.
     */
    boolean hasRecordCount();
    /**
     * <code>optional int32 record_count = 1;</code>
     * @return The recordCount.
     */
    int getRecordCount();

    /**
     * <code>repeated .exec.shared.SerializedField field = 2;</code>
     */
    java.util.List<org.apache.drill.exec.proto.UserBitShared.SerializedField> 
        getFieldList();
    /**
     * <code>repeated .exec.shared.SerializedField field = 2;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.SerializedField getField(int index);
    /**
     * <code>repeated .exec.shared.SerializedField field = 2;</code>
     */
    int getFieldCount();
    /**
     * <code>repeated .exec.shared.SerializedField field = 2;</code>
     */
    java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.SerializedFieldOrBuilder> 
        getFieldOrBuilderList();
    /**
     * <code>repeated .exec.shared.SerializedField field = 2;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.SerializedFieldOrBuilder getFieldOrBuilder(
        int index);

    /**
     * <code>optional bool carries_two_byte_selection_vector = 3;</code>
     * @return Whether the carriesTwoByteSelectionVector field is set.
     */
    boolean hasCarriesTwoByteSelectionVector();
    /**
     * <code>optional bool carries_two_byte_selection_vector = 3;</code>
     * @return The carriesTwoByteSelectionVector.
     */
    boolean getCarriesTwoByteSelectionVector();

    /**
     * <pre>
     * The value is set when result set is disabled and its value corresponds to number
     * of rows affected by query (see JDBC java.sql.ResultSet#getUpdateCount())
     * </pre>
     *
     * <code>optional int32 affected_rows_count = 4;</code>
     * @return Whether the affectedRowsCount field is set.
     */
    boolean hasAffectedRowsCount();
    /**
     * <pre>
     * The value is set when result set is disabled and its value corresponds to number
     * of rows affected by query (see JDBC java.sql.ResultSet#getUpdateCount())
     * </pre>
     *
     * <code>optional int32 affected_rows_count = 4;</code>
     * @return The affectedRowsCount.
     */
    int getAffectedRowsCount();
  }
  /**
   * Protobuf type {@code exec.shared.RecordBatchDef}
   */
  public static final class RecordBatchDef extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.RecordBatchDef)
      RecordBatchDefOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use RecordBatchDef.newBuilder() to construct.
    private RecordBatchDef(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private RecordBatchDef() {
      field_ = java.util.Collections.emptyList();
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new RecordBatchDef();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_RecordBatchDef_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_RecordBatchDef_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserBitShared.RecordBatchDef.class, org.apache.drill.exec.proto.UserBitShared.RecordBatchDef.Builder.class);
    }

    private int bitField0_;
    public static final int RECORD_COUNT_FIELD_NUMBER = 1;
    private int recordCount_;
    /**
     * <code>optional int32 record_count = 1;</code>
     * @return Whether the recordCount field is set.
     */
    @java.lang.Override
    public boolean hasRecordCount() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional int32 record_count = 1;</code>
     * @return The recordCount.
     */
    @java.lang.Override
    public int getRecordCount() {
      return recordCount_;
    }

    public static final int FIELD_FIELD_NUMBER = 2;
    private java.util.List<org.apache.drill.exec.proto.UserBitShared.SerializedField> field_;
    /**
     * <code>repeated .exec.shared.SerializedField field = 2;</code>
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.UserBitShared.SerializedField> getFieldList() {
      return field_;
    }
    /**
     * <code>repeated .exec.shared.SerializedField field = 2;</code>
     */
    @java.lang.Override
    public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.SerializedFieldOrBuilder> 
        getFieldOrBuilderList() {
      return field_;
    }
    /**
     * <code>repeated .exec.shared.SerializedField field = 2;</code>
     */
    @java.lang.Override
    public int getFieldCount() {
      return field_.size();
    }
    /**
     * <code>repeated .exec.shared.SerializedField field = 2;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.SerializedField getField(int index) {
      return field_.get(index);
    }
    /**
     * <code>repeated .exec.shared.SerializedField field = 2;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.SerializedFieldOrBuilder getFieldOrBuilder(
        int index) {
      return field_.get(index);
    }

    public static final int CARRIES_TWO_BYTE_SELECTION_VECTOR_FIELD_NUMBER = 3;
    private boolean carriesTwoByteSelectionVector_;
    /**
     * <code>optional bool carries_two_byte_selection_vector = 3;</code>
     * @return Whether the carriesTwoByteSelectionVector field is set.
     */
    @java.lang.Override
    public boolean hasCarriesTwoByteSelectionVector() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional bool carries_two_byte_selection_vector = 3;</code>
     * @return The carriesTwoByteSelectionVector.
     */
    @java.lang.Override
    public boolean getCarriesTwoByteSelectionVector() {
      return carriesTwoByteSelectionVector_;
    }

    public static final int AFFECTED_ROWS_COUNT_FIELD_NUMBER = 4;
    private int affectedRowsCount_;
    /**
     * <pre>
     * The value is set when result set is disabled and its value corresponds to number
     * of rows affected by query (see JDBC java.sql.ResultSet#getUpdateCount())
     * </pre>
     *
     * <code>optional int32 affected_rows_count = 4;</code>
     * @return Whether the affectedRowsCount field is set.
     */
    @java.lang.Override
    public boolean hasAffectedRowsCount() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <pre>
     * The value is set when result set is disabled and its value corresponds to number
     * of rows affected by query (see JDBC java.sql.ResultSet#getUpdateCount())
     * </pre>
     *
     * <code>optional int32 affected_rows_count = 4;</code>
     * @return The affectedRowsCount.
     */
    @java.lang.Override
    public int getAffectedRowsCount() {
      return affectedRowsCount_;
    }

    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 (((bitField0_ & 0x00000001) != 0)) {
        output.writeInt32(1, recordCount_);
      }
      for (int i = 0; i < field_.size(); i++) {
        output.writeMessage(2, field_.get(i));
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeBool(3, carriesTwoByteSelectionVector_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeInt32(4, affectedRowsCount_);
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(1, recordCount_);
      }
      for (int i = 0; i < field_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, field_.get(i));
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(3, carriesTwoByteSelectionVector_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(4, affectedRowsCount_);
      }
      size += getUnknownFields().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.drill.exec.proto.UserBitShared.RecordBatchDef)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserBitShared.RecordBatchDef other = (org.apache.drill.exec.proto.UserBitShared.RecordBatchDef) obj;

      if (hasRecordCount() != other.hasRecordCount()) return false;
      if (hasRecordCount()) {
        if (getRecordCount()
            != other.getRecordCount()) return false;
      }
      if (!getFieldList()
          .equals(other.getFieldList())) return false;
      if (hasCarriesTwoByteSelectionVector() != other.hasCarriesTwoByteSelectionVector()) return false;
      if (hasCarriesTwoByteSelectionVector()) {
        if (getCarriesTwoByteSelectionVector()
            != other.getCarriesTwoByteSelectionVector()) return false;
      }
      if (hasAffectedRowsCount() != other.hasAffectedRowsCount()) return false;
      if (hasAffectedRowsCount()) {
        if (getAffectedRowsCount()
            != other.getAffectedRowsCount()) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasRecordCount()) {
        hash = (37 * hash) + RECORD_COUNT_FIELD_NUMBER;
        hash = (53 * hash) + getRecordCount();
      }
      if (getFieldCount() > 0) {
        hash = (37 * hash) + FIELD_FIELD_NUMBER;
        hash = (53 * hash) + getFieldList().hashCode();
      }
      if (hasCarriesTwoByteSelectionVector()) {
        hash = (37 * hash) + CARRIES_TWO_BYTE_SELECTION_VECTOR_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getCarriesTwoByteSelectionVector());
      }
      if (hasAffectedRowsCount()) {
        hash = (37 * hash) + AFFECTED_ROWS_COUNT_FIELD_NUMBER;
        hash = (53 * hash) + getAffectedRowsCount();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserBitShared.RecordBatchDef parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.RecordBatchDef parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.RecordBatchDef parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.RecordBatchDef 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.drill.exec.proto.UserBitShared.RecordBatchDef parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.RecordBatchDef parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.RecordBatchDef parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.RecordBatchDef 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.drill.exec.proto.UserBitShared.RecordBatchDef parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.RecordBatchDef 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.drill.exec.proto.UserBitShared.RecordBatchDef parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.RecordBatchDef 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.drill.exec.proto.UserBitShared.RecordBatchDef 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 exec.shared.RecordBatchDef}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.shared.RecordBatchDef)
        org.apache.drill.exec.proto.UserBitShared.RecordBatchDefOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_RecordBatchDef_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_RecordBatchDef_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserBitShared.RecordBatchDef.class, org.apache.drill.exec.proto.UserBitShared.RecordBatchDef.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserBitShared.RecordBatchDef.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        recordCount_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        if (fieldBuilder_ == null) {
          field_ = java.util.Collections.emptyList();
        } else {
          field_ = null;
          fieldBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        carriesTwoByteSelectionVector_ = false;
        bitField0_ = (bitField0_ & ~0x00000004);
        affectedRowsCount_ = 0;
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_RecordBatchDef_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.RecordBatchDef getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserBitShared.RecordBatchDef.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.RecordBatchDef build() {
        org.apache.drill.exec.proto.UserBitShared.RecordBatchDef result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.RecordBatchDef buildPartial() {
        org.apache.drill.exec.proto.UserBitShared.RecordBatchDef result = new org.apache.drill.exec.proto.UserBitShared.RecordBatchDef(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.recordCount_ = recordCount_;
          to_bitField0_ |= 0x00000001;
        }
        if (fieldBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0)) {
            field_ = java.util.Collections.unmodifiableList(field_);
            bitField0_ = (bitField0_ & ~0x00000002);
          }
          result.field_ = field_;
        } else {
          result.field_ = fieldBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.carriesTwoByteSelectionVector_ = carriesTwoByteSelectionVector_;
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000008) != 0)) {
          result.affectedRowsCount_ = affectedRowsCount_;
          to_bitField0_ |= 0x00000004;
        }
        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.drill.exec.proto.UserBitShared.RecordBatchDef) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.RecordBatchDef)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.RecordBatchDef other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.RecordBatchDef.getDefaultInstance()) return this;
        if (other.hasRecordCount()) {
          setRecordCount(other.getRecordCount());
        }
        if (fieldBuilder_ == null) {
          if (!other.field_.isEmpty()) {
            if (field_.isEmpty()) {
              field_ = other.field_;
              bitField0_ = (bitField0_ & ~0x00000002);
            } else {
              ensureFieldIsMutable();
              field_.addAll(other.field_);
            }
            onChanged();
          }
        } else {
          if (!other.field_.isEmpty()) {
            if (fieldBuilder_.isEmpty()) {
              fieldBuilder_.dispose();
              fieldBuilder_ = null;
              field_ = other.field_;
              bitField0_ = (bitField0_ & ~0x00000002);
              fieldBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getFieldFieldBuilder() : null;
            } else {
              fieldBuilder_.addAllMessages(other.field_);
            }
          }
        }
        if (other.hasCarriesTwoByteSelectionVector()) {
          setCarriesTwoByteSelectionVector(other.getCarriesTwoByteSelectionVector());
        }
        if (other.hasAffectedRowsCount()) {
          setAffectedRowsCount(other.getAffectedRowsCount());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        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 {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                recordCount_ = input.readInt32();
                bitField0_ |= 0x00000001;
                break;
              } // case 8
              case 18: {
                org.apache.drill.exec.proto.UserBitShared.SerializedField m =
                    input.readMessage(
                        org.apache.drill.exec.proto.UserBitShared.SerializedField.PARSER,
                        extensionRegistry);
                if (fieldBuilder_ == null) {
                  ensureFieldIsMutable();
                  field_.add(m);
                } else {
                  fieldBuilder_.addMessage(m);
                }
                break;
              } // case 18
              case 24: {
                carriesTwoByteSelectionVector_ = input.readBool();
                bitField0_ |= 0x00000004;
                break;
              } // case 24
              case 32: {
                affectedRowsCount_ = input.readInt32();
                bitField0_ |= 0x00000008;
                break;
              } // case 32
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private int recordCount_ ;
      /**
       * <code>optional int32 record_count = 1;</code>
       * @return Whether the recordCount field is set.
       */
      @java.lang.Override
      public boolean hasRecordCount() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional int32 record_count = 1;</code>
       * @return The recordCount.
       */
      @java.lang.Override
      public int getRecordCount() {
        return recordCount_;
      }
      /**
       * <code>optional int32 record_count = 1;</code>
       * @param value The recordCount to set.
       * @return This builder for chaining.
       */
      public Builder setRecordCount(int value) {
        bitField0_ |= 0x00000001;
        recordCount_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 record_count = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearRecordCount() {
        bitField0_ = (bitField0_ & ~0x00000001);
        recordCount_ = 0;
        onChanged();
        return this;
      }

      private java.util.List<org.apache.drill.exec.proto.UserBitShared.SerializedField> field_ =
        java.util.Collections.emptyList();
      private void ensureFieldIsMutable() {
        if (!((bitField0_ & 0x00000002) != 0)) {
          field_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserBitShared.SerializedField>(field_);
          bitField0_ |= 0x00000002;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.SerializedField, org.apache.drill.exec.proto.UserBitShared.SerializedField.Builder, org.apache.drill.exec.proto.UserBitShared.SerializedFieldOrBuilder> fieldBuilder_;

      /**
       * <code>repeated .exec.shared.SerializedField field = 2;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserBitShared.SerializedField> getFieldList() {
        if (fieldBuilder_ == null) {
          return java.util.Collections.unmodifiableList(field_);
        } else {
          return fieldBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .exec.shared.SerializedField field = 2;</code>
       */
      public int getFieldCount() {
        if (fieldBuilder_ == null) {
          return field_.size();
        } else {
          return fieldBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .exec.shared.SerializedField field = 2;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.SerializedField getField(int index) {
        if (fieldBuilder_ == null) {
          return field_.get(index);
        } else {
          return fieldBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .exec.shared.SerializedField field = 2;</code>
       */
      public Builder setField(
          int index, org.apache.drill.exec.proto.UserBitShared.SerializedField value) {
        if (fieldBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureFieldIsMutable();
          field_.set(index, value);
          onChanged();
        } else {
          fieldBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.SerializedField field = 2;</code>
       */
      public Builder setField(
          int index, org.apache.drill.exec.proto.UserBitShared.SerializedField.Builder builderForValue) {
        if (fieldBuilder_ == null) {
          ensureFieldIsMutable();
          field_.set(index, builderForValue.build());
          onChanged();
        } else {
          fieldBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.SerializedField field = 2;</code>
       */
      public Builder addField(org.apache.drill.exec.proto.UserBitShared.SerializedField value) {
        if (fieldBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureFieldIsMutable();
          field_.add(value);
          onChanged();
        } else {
          fieldBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.SerializedField field = 2;</code>
       */
      public Builder addField(
          int index, org.apache.drill.exec.proto.UserBitShared.SerializedField value) {
        if (fieldBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureFieldIsMutable();
          field_.add(index, value);
          onChanged();
        } else {
          fieldBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.SerializedField field = 2;</code>
       */
      public Builder addField(
          org.apache.drill.exec.proto.UserBitShared.SerializedField.Builder builderForValue) {
        if (fieldBuilder_ == null) {
          ensureFieldIsMutable();
          field_.add(builderForValue.build());
          onChanged();
        } else {
          fieldBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.SerializedField field = 2;</code>
       */
      public Builder addField(
          int index, org.apache.drill.exec.proto.UserBitShared.SerializedField.Builder builderForValue) {
        if (fieldBuilder_ == null) {
          ensureFieldIsMutable();
          field_.add(index, builderForValue.build());
          onChanged();
        } else {
          fieldBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.SerializedField field = 2;</code>
       */
      public Builder addAllField(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.UserBitShared.SerializedField> values) {
        if (fieldBuilder_ == null) {
          ensureFieldIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, field_);
          onChanged();
        } else {
          fieldBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.SerializedField field = 2;</code>
       */
      public Builder clearField() {
        if (fieldBuilder_ == null) {
          field_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000002);
          onChanged();
        } else {
          fieldBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.SerializedField field = 2;</code>
       */
      public Builder removeField(int index) {
        if (fieldBuilder_ == null) {
          ensureFieldIsMutable();
          field_.remove(index);
          onChanged();
        } else {
          fieldBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.SerializedField field = 2;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.SerializedField.Builder getFieldBuilder(
          int index) {
        return getFieldFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .exec.shared.SerializedField field = 2;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.SerializedFieldOrBuilder getFieldOrBuilder(
          int index) {
        if (fieldBuilder_ == null) {
          return field_.get(index);  } else {
          return fieldBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .exec.shared.SerializedField field = 2;</code>
       */
      public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.SerializedFieldOrBuilder> 
           getFieldOrBuilderList() {
        if (fieldBuilder_ != null) {
          return fieldBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(field_);
        }
      }
      /**
       * <code>repeated .exec.shared.SerializedField field = 2;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.SerializedField.Builder addFieldBuilder() {
        return getFieldFieldBuilder().addBuilder(
            org.apache.drill.exec.proto.UserBitShared.SerializedField.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.shared.SerializedField field = 2;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.SerializedField.Builder addFieldBuilder(
          int index) {
        return getFieldFieldBuilder().addBuilder(
            index, org.apache.drill.exec.proto.UserBitShared.SerializedField.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.shared.SerializedField field = 2;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserBitShared.SerializedField.Builder> 
           getFieldBuilderList() {
        return getFieldFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.SerializedField, org.apache.drill.exec.proto.UserBitShared.SerializedField.Builder, org.apache.drill.exec.proto.UserBitShared.SerializedFieldOrBuilder> 
          getFieldFieldBuilder() {
        if (fieldBuilder_ == null) {
          fieldBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.SerializedField, org.apache.drill.exec.proto.UserBitShared.SerializedField.Builder, org.apache.drill.exec.proto.UserBitShared.SerializedFieldOrBuilder>(
                  field_,
                  ((bitField0_ & 0x00000002) != 0),
                  getParentForChildren(),
                  isClean());
          field_ = null;
        }
        return fieldBuilder_;
      }

      private boolean carriesTwoByteSelectionVector_ ;
      /**
       * <code>optional bool carries_two_byte_selection_vector = 3;</code>
       * @return Whether the carriesTwoByteSelectionVector field is set.
       */
      @java.lang.Override
      public boolean hasCarriesTwoByteSelectionVector() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional bool carries_two_byte_selection_vector = 3;</code>
       * @return The carriesTwoByteSelectionVector.
       */
      @java.lang.Override
      public boolean getCarriesTwoByteSelectionVector() {
        return carriesTwoByteSelectionVector_;
      }
      /**
       * <code>optional bool carries_two_byte_selection_vector = 3;</code>
       * @param value The carriesTwoByteSelectionVector to set.
       * @return This builder for chaining.
       */
      public Builder setCarriesTwoByteSelectionVector(boolean value) {
        bitField0_ |= 0x00000004;
        carriesTwoByteSelectionVector_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool carries_two_byte_selection_vector = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearCarriesTwoByteSelectionVector() {
        bitField0_ = (bitField0_ & ~0x00000004);
        carriesTwoByteSelectionVector_ = false;
        onChanged();
        return this;
      }

      private int affectedRowsCount_ ;
      /**
       * <pre>
       * The value is set when result set is disabled and its value corresponds to number
       * of rows affected by query (see JDBC java.sql.ResultSet#getUpdateCount())
       * </pre>
       *
       * <code>optional int32 affected_rows_count = 4;</code>
       * @return Whether the affectedRowsCount field is set.
       */
      @java.lang.Override
      public boolean hasAffectedRowsCount() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <pre>
       * The value is set when result set is disabled and its value corresponds to number
       * of rows affected by query (see JDBC java.sql.ResultSet#getUpdateCount())
       * </pre>
       *
       * <code>optional int32 affected_rows_count = 4;</code>
       * @return The affectedRowsCount.
       */
      @java.lang.Override
      public int getAffectedRowsCount() {
        return affectedRowsCount_;
      }
      /**
       * <pre>
       * The value is set when result set is disabled and its value corresponds to number
       * of rows affected by query (see JDBC java.sql.ResultSet#getUpdateCount())
       * </pre>
       *
       * <code>optional int32 affected_rows_count = 4;</code>
       * @param value The affectedRowsCount to set.
       * @return This builder for chaining.
       */
      public Builder setAffectedRowsCount(int value) {
        bitField0_ |= 0x00000008;
        affectedRowsCount_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The value is set when result set is disabled and its value corresponds to number
       * of rows affected by query (see JDBC java.sql.ResultSet#getUpdateCount())
       * </pre>
       *
       * <code>optional int32 affected_rows_count = 4;</code>
       * @return This builder for chaining.
       */
      public Builder clearAffectedRowsCount() {
        bitField0_ = (bitField0_ & ~0x00000008);
        affectedRowsCount_ = 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:exec.shared.RecordBatchDef)
    }

    // @@protoc_insertion_point(class_scope:exec.shared.RecordBatchDef)
    private static final org.apache.drill.exec.proto.UserBitShared.RecordBatchDef DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserBitShared.RecordBatchDef();
    }

    public static org.apache.drill.exec.proto.UserBitShared.RecordBatchDef getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<RecordBatchDef>
        PARSER = new com.google.protobuf.AbstractParser<RecordBatchDef>() {
      @java.lang.Override
      public RecordBatchDef parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

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

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

    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.RecordBatchDef getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface NamePartOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.shared.NamePart)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional .exec.shared.NamePart.Type type = 1;</code>
     * @return Whether the type field is set.
     */
    boolean hasType();
    /**
     * <code>optional .exec.shared.NamePart.Type type = 1;</code>
     * @return The type.
     */
    org.apache.drill.exec.proto.UserBitShared.NamePart.Type getType();

    /**
     * <code>optional string name = 2;</code>
     * @return Whether the name field is set.
     */
    boolean hasName();
    /**
     * <code>optional string name = 2;</code>
     * @return The name.
     */
    java.lang.String getName();
    /**
     * <code>optional string name = 2;</code>
     * @return The bytes for name.
     */
    com.google.protobuf.ByteString
        getNameBytes();

    /**
     * <code>optional .exec.shared.NamePart child = 3;</code>
     * @return Whether the child field is set.
     */
    boolean hasChild();
    /**
     * <code>optional .exec.shared.NamePart child = 3;</code>
     * @return The child.
     */
    org.apache.drill.exec.proto.UserBitShared.NamePart getChild();
    /**
     * <code>optional .exec.shared.NamePart child = 3;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.NamePartOrBuilder getChildOrBuilder();
  }
  /**
   * Protobuf type {@code exec.shared.NamePart}
   */
  public static final class NamePart extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.NamePart)
      NamePartOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use NamePart.newBuilder() to construct.
    private NamePart(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private NamePart() {
      type_ = 0;
      name_ = "";
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new NamePart();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_NamePart_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_NamePart_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserBitShared.NamePart.class, org.apache.drill.exec.proto.UserBitShared.NamePart.Builder.class);
    }

    /**
     * Protobuf enum {@code exec.shared.NamePart.Type}
     */
    public enum Type
        implements com.google.protobuf.ProtocolMessageEnum {
      /**
       * <code>NAME = 0;</code>
       */
      NAME(0),
      /**
       * <code>ARRAY = 1;</code>
       */
      ARRAY(1),
      ;

      /**
       * <code>NAME = 0;</code>
       */
      public static final int NAME_VALUE = 0;
      /**
       * <code>ARRAY = 1;</code>
       */
      public static final int ARRAY_VALUE = 1;


      public final int getNumber() {
        return value;
      }

      /**
       * @param value The numeric wire value of the corresponding enum entry.
       * @return The enum associated with the given numeric wire value.
       * @deprecated Use {@link #forNumber(int)} instead.
       */
      @java.lang.Deprecated
      public static Type valueOf(int value) {
        return forNumber(value);
      }

      /**
       * @param value The numeric wire value of the corresponding enum entry.
       * @return The enum associated with the given numeric wire value.
       */
      public static Type forNumber(int value) {
        switch (value) {
          case 0: return NAME;
          case 1: return ARRAY;
          default: return null;
        }
      }

      public static com.google.protobuf.Internal.EnumLiteMap<Type>
          internalGetValueMap() {
        return internalValueMap;
      }
      private static final com.google.protobuf.Internal.EnumLiteMap<
          Type> internalValueMap =
            new com.google.protobuf.Internal.EnumLiteMap<Type>() {
              public Type findValueByNumber(int number) {
                return Type.forNumber(number);
              }
            };

      public final com.google.protobuf.Descriptors.EnumValueDescriptor
          getValueDescriptor() {
        return getDescriptor().getValues().get(ordinal());
      }
      public final com.google.protobuf.Descriptors.EnumDescriptor
          getDescriptorForType() {
        return getDescriptor();
      }
      public static final com.google.protobuf.Descriptors.EnumDescriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserBitShared.NamePart.getDescriptor().getEnumTypes().get(0);
      }

      private static final Type[] VALUES = values();

      public static Type valueOf(
          com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
        if (desc.getType() != getDescriptor()) {
          throw new java.lang.IllegalArgumentException(
            "EnumValueDescriptor is not for this type.");
        }
        return VALUES[desc.getIndex()];
      }

      private final int value;

      private Type(int value) {
        this.value = value;
      }

      // @@protoc_insertion_point(enum_scope:exec.shared.NamePart.Type)
    }

    private int bitField0_;
    public static final int TYPE_FIELD_NUMBER = 1;
    private int type_;
    /**
     * <code>optional .exec.shared.NamePart.Type type = 1;</code>
     * @return Whether the type field is set.
     */
    @java.lang.Override public boolean hasType() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional .exec.shared.NamePart.Type type = 1;</code>
     * @return The type.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserBitShared.NamePart.Type getType() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserBitShared.NamePart.Type result = org.apache.drill.exec.proto.UserBitShared.NamePart.Type.valueOf(type_);
      return result == null ? org.apache.drill.exec.proto.UserBitShared.NamePart.Type.NAME : result;
    }

    public static final int NAME_FIELD_NUMBER = 2;
    private volatile java.lang.Object name_;
    /**
     * <code>optional string name = 2;</code>
     * @return Whether the name field is set.
     */
    @java.lang.Override
    public boolean hasName() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional string name = 2;</code>
     * @return The name.
     */
    @java.lang.Override
    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();
        if (bs.isValidUtf8()) {
          name_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string name = 2;</code>
     * @return The bytes for name.
     */
    @java.lang.Override
    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 CHILD_FIELD_NUMBER = 3;
    private org.apache.drill.exec.proto.UserBitShared.NamePart child_;
    /**
     * <code>optional .exec.shared.NamePart child = 3;</code>
     * @return Whether the child field is set.
     */
    @java.lang.Override
    public boolean hasChild() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional .exec.shared.NamePart child = 3;</code>
     * @return The child.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.NamePart getChild() {
      return child_ == null ? org.apache.drill.exec.proto.UserBitShared.NamePart.getDefaultInstance() : child_;
    }
    /**
     * <code>optional .exec.shared.NamePart child = 3;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.NamePartOrBuilder getChildOrBuilder() {
      return child_ == null ? org.apache.drill.exec.proto.UserBitShared.NamePart.getDefaultInstance() : child_;
    }

    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 (((bitField0_ & 0x00000001) != 0)) {
        output.writeEnum(1, type_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, name_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeMessage(3, getChild());
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(1, type_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, name_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, getChild());
      }
      size += getUnknownFields().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.drill.exec.proto.UserBitShared.NamePart)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserBitShared.NamePart other = (org.apache.drill.exec.proto.UserBitShared.NamePart) obj;

      if (hasType() != other.hasType()) return false;
      if (hasType()) {
        if (type_ != other.type_) return false;
      }
      if (hasName() != other.hasName()) return false;
      if (hasName()) {
        if (!getName()
            .equals(other.getName())) return false;
      }
      if (hasChild() != other.hasChild()) return false;
      if (hasChild()) {
        if (!getChild()
            .equals(other.getChild())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasType()) {
        hash = (37 * hash) + TYPE_FIELD_NUMBER;
        hash = (53 * hash) + type_;
      }
      if (hasName()) {
        hash = (37 * hash) + NAME_FIELD_NUMBER;
        hash = (53 * hash) + getName().hashCode();
      }
      if (hasChild()) {
        hash = (37 * hash) + CHILD_FIELD_NUMBER;
        hash = (53 * hash) + getChild().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserBitShared.NamePart parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.NamePart parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.NamePart parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.NamePart 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.drill.exec.proto.UserBitShared.NamePart parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.NamePart parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.NamePart parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.NamePart 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.drill.exec.proto.UserBitShared.NamePart parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.NamePart 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.drill.exec.proto.UserBitShared.NamePart parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.NamePart 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.drill.exec.proto.UserBitShared.NamePart 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 exec.shared.NamePart}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.shared.NamePart)
        org.apache.drill.exec.proto.UserBitShared.NamePartOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_NamePart_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_NamePart_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserBitShared.NamePart.class, org.apache.drill.exec.proto.UserBitShared.NamePart.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserBitShared.NamePart.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getChildFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        type_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        name_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        if (childBuilder_ == null) {
          child_ = null;
        } else {
          childBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_NamePart_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.NamePart getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserBitShared.NamePart.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.NamePart build() {
        org.apache.drill.exec.proto.UserBitShared.NamePart result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.NamePart buildPartial() {
        org.apache.drill.exec.proto.UserBitShared.NamePart result = new org.apache.drill.exec.proto.UserBitShared.NamePart(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.type_ = type_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          to_bitField0_ |= 0x00000002;
        }
        result.name_ = name_;
        if (((from_bitField0_ & 0x00000004) != 0)) {
          if (childBuilder_ == null) {
            result.child_ = child_;
          } else {
            result.child_ = childBuilder_.build();
          }
          to_bitField0_ |= 0x00000004;
        }
        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.drill.exec.proto.UserBitShared.NamePart) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.NamePart)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.NamePart other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.NamePart.getDefaultInstance()) return this;
        if (other.hasType()) {
          setType(other.getType());
        }
        if (other.hasName()) {
          bitField0_ |= 0x00000002;
          name_ = other.name_;
          onChanged();
        }
        if (other.hasChild()) {
          mergeChild(other.getChild());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        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 {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserBitShared.NamePart.Type tmpValue =
                    org.apache.drill.exec.proto.UserBitShared.NamePart.Type.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(1, tmpRaw);
                } else {
                  type_ = tmpRaw;
                  bitField0_ |= 0x00000001;
                }
                break;
              } // case 8
              case 18: {
                name_ = input.readBytes();
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              case 26: {
                input.readMessage(
                    getChildFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000004;
                break;
              } // case 26
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private int type_ = 0;
      /**
       * <code>optional .exec.shared.NamePart.Type type = 1;</code>
       * @return Whether the type field is set.
       */
      @java.lang.Override public boolean hasType() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .exec.shared.NamePart.Type type = 1;</code>
       * @return The type.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.NamePart.Type getType() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserBitShared.NamePart.Type result = org.apache.drill.exec.proto.UserBitShared.NamePart.Type.valueOf(type_);
        return result == null ? org.apache.drill.exec.proto.UserBitShared.NamePart.Type.NAME : result;
      }
      /**
       * <code>optional .exec.shared.NamePart.Type type = 1;</code>
       * @param value The type to set.
       * @return This builder for chaining.
       */
      public Builder setType(org.apache.drill.exec.proto.UserBitShared.NamePart.Type value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000001;
        type_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .exec.shared.NamePart.Type type = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearType() {
        bitField0_ = (bitField0_ & ~0x00000001);
        type_ = 0;
        onChanged();
        return this;
      }

      private java.lang.Object name_ = "";
      /**
       * <code>optional string name = 2;</code>
       * @return Whether the name field is set.
       */
      public boolean hasName() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional string name = 2;</code>
       * @return The name.
       */
      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();
          if (bs.isValidUtf8()) {
            name_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string name = 2;</code>
       * @return The bytes for name.
       */
      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>optional string name = 2;</code>
       * @param value The name to set.
       * @return This builder for chaining.
       */
      public Builder setName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        name_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string name = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearName() {
        bitField0_ = (bitField0_ & ~0x00000002);
        name_ = getDefaultInstance().getName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string name = 2;</code>
       * @param value The bytes for name to set.
       * @return This builder for chaining.
       */
      public Builder setNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        name_ = value;
        onChanged();
        return this;
      }

      private org.apache.drill.exec.proto.UserBitShared.NamePart child_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.NamePart, org.apache.drill.exec.proto.UserBitShared.NamePart.Builder, org.apache.drill.exec.proto.UserBitShared.NamePartOrBuilder> childBuilder_;
      /**
       * <code>optional .exec.shared.NamePart child = 3;</code>
       * @return Whether the child field is set.
       */
      public boolean hasChild() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional .exec.shared.NamePart child = 3;</code>
       * @return The child.
       */
      public org.apache.drill.exec.proto.UserBitShared.NamePart getChild() {
        if (childBuilder_ == null) {
          return child_ == null ? org.apache.drill.exec.proto.UserBitShared.NamePart.getDefaultInstance() : child_;
        } else {
          return childBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.shared.NamePart child = 3;</code>
       */
      public Builder setChild(org.apache.drill.exec.proto.UserBitShared.NamePart value) {
        if (childBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          child_ = value;
          onChanged();
        } else {
          childBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.shared.NamePart child = 3;</code>
       */
      public Builder setChild(
          org.apache.drill.exec.proto.UserBitShared.NamePart.Builder builderForValue) {
        if (childBuilder_ == null) {
          child_ = builderForValue.build();
          onChanged();
        } else {
          childBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.shared.NamePart child = 3;</code>
       */
      public Builder mergeChild(org.apache.drill.exec.proto.UserBitShared.NamePart value) {
        if (childBuilder_ == null) {
          if (((bitField0_ & 0x00000004) != 0) &&
              child_ != null &&
              child_ != org.apache.drill.exec.proto.UserBitShared.NamePart.getDefaultInstance()) {
            child_ =
              org.apache.drill.exec.proto.UserBitShared.NamePart.newBuilder(child_).mergeFrom(value).buildPartial();
          } else {
            child_ = value;
          }
          onChanged();
        } else {
          childBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.shared.NamePart child = 3;</code>
       */
      public Builder clearChild() {
        if (childBuilder_ == null) {
          child_ = null;
          onChanged();
        } else {
          childBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }
      /**
       * <code>optional .exec.shared.NamePart child = 3;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.NamePart.Builder getChildBuilder() {
        bitField0_ |= 0x00000004;
        onChanged();
        return getChildFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.shared.NamePart child = 3;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.NamePartOrBuilder getChildOrBuilder() {
        if (childBuilder_ != null) {
          return childBuilder_.getMessageOrBuilder();
        } else {
          return child_ == null ?
              org.apache.drill.exec.proto.UserBitShared.NamePart.getDefaultInstance() : child_;
        }
      }
      /**
       * <code>optional .exec.shared.NamePart child = 3;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.NamePart, org.apache.drill.exec.proto.UserBitShared.NamePart.Builder, org.apache.drill.exec.proto.UserBitShared.NamePartOrBuilder> 
          getChildFieldBuilder() {
        if (childBuilder_ == null) {
          childBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.NamePart, org.apache.drill.exec.proto.UserBitShared.NamePart.Builder, org.apache.drill.exec.proto.UserBitShared.NamePartOrBuilder>(
                  getChild(),
                  getParentForChildren(),
                  isClean());
          child_ = null;
        }
        return childBuilder_;
      }
      @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:exec.shared.NamePart)
    }

    // @@protoc_insertion_point(class_scope:exec.shared.NamePart)
    private static final org.apache.drill.exec.proto.UserBitShared.NamePart DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserBitShared.NamePart();
    }

    public static org.apache.drill.exec.proto.UserBitShared.NamePart getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<NamePart>
        PARSER = new com.google.protobuf.AbstractParser<NamePart>() {
      @java.lang.Override
      public NamePart parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

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

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

    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.NamePart getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface SerializedFieldOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.shared.SerializedField)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <pre>
     * the type associated with this field.
     * </pre>
     *
     * <code>optional .common.MajorType major_type = 1;</code>
     * @return Whether the majorType field is set.
     */
    boolean hasMajorType();
    /**
     * <pre>
     * the type associated with this field.
     * </pre>
     *
     * <code>optional .common.MajorType major_type = 1;</code>
     * @return The majorType.
     */
    org.apache.drill.common.types.TypeProtos.MajorType getMajorType();
    /**
     * <pre>
     * the type associated with this field.
     * </pre>
     *
     * <code>optional .common.MajorType major_type = 1;</code>
     */
    org.apache.drill.common.types.TypeProtos.MajorTypeOrBuilder getMajorTypeOrBuilder();

    /**
     * <code>optional .exec.shared.NamePart name_part = 2;</code>
     * @return Whether the namePart field is set.
     */
    boolean hasNamePart();
    /**
     * <code>optional .exec.shared.NamePart name_part = 2;</code>
     * @return The namePart.
     */
    org.apache.drill.exec.proto.UserBitShared.NamePart getNamePart();
    /**
     * <code>optional .exec.shared.NamePart name_part = 2;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.NamePartOrBuilder getNamePartOrBuilder();

    /**
     * <pre>
     * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
     * </pre>
     *
     * <code>repeated .exec.shared.SerializedField child = 3;</code>
     */
    java.util.List<org.apache.drill.exec.proto.UserBitShared.SerializedField> 
        getChildList();
    /**
     * <pre>
     * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
     * </pre>
     *
     * <code>repeated .exec.shared.SerializedField child = 3;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.SerializedField getChild(int index);
    /**
     * <pre>
     * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
     * </pre>
     *
     * <code>repeated .exec.shared.SerializedField child = 3;</code>
     */
    int getChildCount();
    /**
     * <pre>
     * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
     * </pre>
     *
     * <code>repeated .exec.shared.SerializedField child = 3;</code>
     */
    java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.SerializedFieldOrBuilder> 
        getChildOrBuilderList();
    /**
     * <pre>
     * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
     * </pre>
     *
     * <code>repeated .exec.shared.SerializedField child = 3;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.SerializedFieldOrBuilder getChildOrBuilder(
        int index);

    /**
     * <code>optional int32 value_count = 4;</code>
     * @return Whether the valueCount field is set.
     */
    boolean hasValueCount();
    /**
     * <code>optional int32 value_count = 4;</code>
     * @return The valueCount.
     */
    int getValueCount();

    /**
     * <code>optional int32 var_byte_length = 5;</code>
     * @return Whether the varByteLength field is set.
     */
    boolean hasVarByteLength();
    /**
     * <code>optional int32 var_byte_length = 5;</code>
     * @return The varByteLength.
     */
    int getVarByteLength();

    /**
     * <code>optional int32 buffer_length = 7;</code>
     * @return Whether the bufferLength field is set.
     */
    boolean hasBufferLength();
    /**
     * <code>optional int32 buffer_length = 7;</code>
     * @return The bufferLength.
     */
    int getBufferLength();
  }
  /**
   * Protobuf type {@code exec.shared.SerializedField}
   */
  public static final class SerializedField extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.SerializedField)
      SerializedFieldOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use SerializedField.newBuilder() to construct.
    private SerializedField(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private SerializedField() {
      child_ = java.util.Collections.emptyList();
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new SerializedField();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_SerializedField_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_SerializedField_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserBitShared.SerializedField.class, org.apache.drill.exec.proto.UserBitShared.SerializedField.Builder.class);
    }

    private int bitField0_;
    public static final int MAJOR_TYPE_FIELD_NUMBER = 1;
    private org.apache.drill.common.types.TypeProtos.MajorType majorType_;
    /**
     * <pre>
     * the type associated with this field.
     * </pre>
     *
     * <code>optional .common.MajorType major_type = 1;</code>
     * @return Whether the majorType field is set.
     */
    @java.lang.Override
    public boolean hasMajorType() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <pre>
     * the type associated with this field.
     * </pre>
     *
     * <code>optional .common.MajorType major_type = 1;</code>
     * @return The majorType.
     */
    @java.lang.Override
    public org.apache.drill.common.types.TypeProtos.MajorType getMajorType() {
      return majorType_ == null ? org.apache.drill.common.types.TypeProtos.MajorType.getDefaultInstance() : majorType_;
    }
    /**
     * <pre>
     * the type associated with this field.
     * </pre>
     *
     * <code>optional .common.MajorType major_type = 1;</code>
     */
    @java.lang.Override
    public org.apache.drill.common.types.TypeProtos.MajorTypeOrBuilder getMajorTypeOrBuilder() {
      return majorType_ == null ? org.apache.drill.common.types.TypeProtos.MajorType.getDefaultInstance() : majorType_;
    }

    public static final int NAME_PART_FIELD_NUMBER = 2;
    private org.apache.drill.exec.proto.UserBitShared.NamePart namePart_;
    /**
     * <code>optional .exec.shared.NamePart name_part = 2;</code>
     * @return Whether the namePart field is set.
     */
    @java.lang.Override
    public boolean hasNamePart() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .exec.shared.NamePart name_part = 2;</code>
     * @return The namePart.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.NamePart getNamePart() {
      return namePart_ == null ? org.apache.drill.exec.proto.UserBitShared.NamePart.getDefaultInstance() : namePart_;
    }
    /**
     * <code>optional .exec.shared.NamePart name_part = 2;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.NamePartOrBuilder getNamePartOrBuilder() {
      return namePart_ == null ? org.apache.drill.exec.proto.UserBitShared.NamePart.getDefaultInstance() : namePart_;
    }

    public static final int CHILD_FIELD_NUMBER = 3;
    private java.util.List<org.apache.drill.exec.proto.UserBitShared.SerializedField> child_;
    /**
     * <pre>
     * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
     * </pre>
     *
     * <code>repeated .exec.shared.SerializedField child = 3;</code>
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.UserBitShared.SerializedField> getChildList() {
      return child_;
    }
    /**
     * <pre>
     * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
     * </pre>
     *
     * <code>repeated .exec.shared.SerializedField child = 3;</code>
     */
    @java.lang.Override
    public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.SerializedFieldOrBuilder> 
        getChildOrBuilderList() {
      return child_;
    }
    /**
     * <pre>
     * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
     * </pre>
     *
     * <code>repeated .exec.shared.SerializedField child = 3;</code>
     */
    @java.lang.Override
    public int getChildCount() {
      return child_.size();
    }
    /**
     * <pre>
     * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
     * </pre>
     *
     * <code>repeated .exec.shared.SerializedField child = 3;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.SerializedField getChild(int index) {
      return child_.get(index);
    }
    /**
     * <pre>
     * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
     * </pre>
     *
     * <code>repeated .exec.shared.SerializedField child = 3;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.SerializedFieldOrBuilder getChildOrBuilder(
        int index) {
      return child_.get(index);
    }

    public static final int VALUE_COUNT_FIELD_NUMBER = 4;
    private int valueCount_;
    /**
     * <code>optional int32 value_count = 4;</code>
     * @return Whether the valueCount field is set.
     */
    @java.lang.Override
    public boolean hasValueCount() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional int32 value_count = 4;</code>
     * @return The valueCount.
     */
    @java.lang.Override
    public int getValueCount() {
      return valueCount_;
    }

    public static final int VAR_BYTE_LENGTH_FIELD_NUMBER = 5;
    private int varByteLength_;
    /**
     * <code>optional int32 var_byte_length = 5;</code>
     * @return Whether the varByteLength field is set.
     */
    @java.lang.Override
    public boolean hasVarByteLength() {
      return ((bitField0_ & 0x00000008) != 0);
    }
    /**
     * <code>optional int32 var_byte_length = 5;</code>
     * @return The varByteLength.
     */
    @java.lang.Override
    public int getVarByteLength() {
      return varByteLength_;
    }

    public static final int BUFFER_LENGTH_FIELD_NUMBER = 7;
    private int bufferLength_;
    /**
     * <code>optional int32 buffer_length = 7;</code>
     * @return Whether the bufferLength field is set.
     */
    @java.lang.Override
    public boolean hasBufferLength() {
      return ((bitField0_ & 0x00000010) != 0);
    }
    /**
     * <code>optional int32 buffer_length = 7;</code>
     * @return The bufferLength.
     */
    @java.lang.Override
    public int getBufferLength() {
      return bufferLength_;
    }

    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 (((bitField0_ & 0x00000001) != 0)) {
        output.writeMessage(1, getMajorType());
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeMessage(2, getNamePart());
      }
      for (int i = 0; i < child_.size(); i++) {
        output.writeMessage(3, child_.get(i));
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeInt32(4, valueCount_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        output.writeInt32(5, varByteLength_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        output.writeInt32(7, bufferLength_);
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, getMajorType());
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, getNamePart());
      }
      for (int i = 0; i < child_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, child_.get(i));
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(4, valueCount_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(5, varByteLength_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(7, bufferLength_);
      }
      size += getUnknownFields().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.drill.exec.proto.UserBitShared.SerializedField)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserBitShared.SerializedField other = (org.apache.drill.exec.proto.UserBitShared.SerializedField) obj;

      if (hasMajorType() != other.hasMajorType()) return false;
      if (hasMajorType()) {
        if (!getMajorType()
            .equals(other.getMajorType())) return false;
      }
      if (hasNamePart() != other.hasNamePart()) return false;
      if (hasNamePart()) {
        if (!getNamePart()
            .equals(other.getNamePart())) return false;
      }
      if (!getChildList()
          .equals(other.getChildList())) return false;
      if (hasValueCount() != other.hasValueCount()) return false;
      if (hasValueCount()) {
        if (getValueCount()
            != other.getValueCount()) return false;
      }
      if (hasVarByteLength() != other.hasVarByteLength()) return false;
      if (hasVarByteLength()) {
        if (getVarByteLength()
            != other.getVarByteLength()) return false;
      }
      if (hasBufferLength() != other.hasBufferLength()) return false;
      if (hasBufferLength()) {
        if (getBufferLength()
            != other.getBufferLength()) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasMajorType()) {
        hash = (37 * hash) + MAJOR_TYPE_FIELD_NUMBER;
        hash = (53 * hash) + getMajorType().hashCode();
      }
      if (hasNamePart()) {
        hash = (37 * hash) + NAME_PART_FIELD_NUMBER;
        hash = (53 * hash) + getNamePart().hashCode();
      }
      if (getChildCount() > 0) {
        hash = (37 * hash) + CHILD_FIELD_NUMBER;
        hash = (53 * hash) + getChildList().hashCode();
      }
      if (hasValueCount()) {
        hash = (37 * hash) + VALUE_COUNT_FIELD_NUMBER;
        hash = (53 * hash) + getValueCount();
      }
      if (hasVarByteLength()) {
        hash = (37 * hash) + VAR_BYTE_LENGTH_FIELD_NUMBER;
        hash = (53 * hash) + getVarByteLength();
      }
      if (hasBufferLength()) {
        hash = (37 * hash) + BUFFER_LENGTH_FIELD_NUMBER;
        hash = (53 * hash) + getBufferLength();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserBitShared.SerializedField parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.SerializedField parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.SerializedField parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.SerializedField 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.drill.exec.proto.UserBitShared.SerializedField parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.SerializedField parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.SerializedField parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.SerializedField 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.drill.exec.proto.UserBitShared.SerializedField parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.SerializedField 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.drill.exec.proto.UserBitShared.SerializedField parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.SerializedField 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.drill.exec.proto.UserBitShared.SerializedField 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 exec.shared.SerializedField}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.shared.SerializedField)
        org.apache.drill.exec.proto.UserBitShared.SerializedFieldOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_SerializedField_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_SerializedField_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserBitShared.SerializedField.class, org.apache.drill.exec.proto.UserBitShared.SerializedField.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserBitShared.SerializedField.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getMajorTypeFieldBuilder();
          getNamePartFieldBuilder();
          getChildFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        if (majorTypeBuilder_ == null) {
          majorType_ = null;
        } else {
          majorTypeBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        if (namePartBuilder_ == null) {
          namePart_ = null;
        } else {
          namePartBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        if (childBuilder_ == null) {
          child_ = java.util.Collections.emptyList();
        } else {
          child_ = null;
          childBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        valueCount_ = 0;
        bitField0_ = (bitField0_ & ~0x00000008);
        varByteLength_ = 0;
        bitField0_ = (bitField0_ & ~0x00000010);
        bufferLength_ = 0;
        bitField0_ = (bitField0_ & ~0x00000020);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_SerializedField_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.SerializedField getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserBitShared.SerializedField.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.SerializedField build() {
        org.apache.drill.exec.proto.UserBitShared.SerializedField result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.SerializedField buildPartial() {
        org.apache.drill.exec.proto.UserBitShared.SerializedField result = new org.apache.drill.exec.proto.UserBitShared.SerializedField(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          if (majorTypeBuilder_ == null) {
            result.majorType_ = majorType_;
          } else {
            result.majorType_ = majorTypeBuilder_.build();
          }
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          if (namePartBuilder_ == null) {
            result.namePart_ = namePart_;
          } else {
            result.namePart_ = namePartBuilder_.build();
          }
          to_bitField0_ |= 0x00000002;
        }
        if (childBuilder_ == null) {
          if (((bitField0_ & 0x00000004) != 0)) {
            child_ = java.util.Collections.unmodifiableList(child_);
            bitField0_ = (bitField0_ & ~0x00000004);
          }
          result.child_ = child_;
        } else {
          result.child_ = childBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000008) != 0)) {
          result.valueCount_ = valueCount_;
          to_bitField0_ |= 0x00000004;
        }
        if (((from_bitField0_ & 0x00000010) != 0)) {
          result.varByteLength_ = varByteLength_;
          to_bitField0_ |= 0x00000008;
        }
        if (((from_bitField0_ & 0x00000020) != 0)) {
          result.bufferLength_ = bufferLength_;
          to_bitField0_ |= 0x00000010;
        }
        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.drill.exec.proto.UserBitShared.SerializedField) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.SerializedField)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.SerializedField other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.SerializedField.getDefaultInstance()) return this;
        if (other.hasMajorType()) {
          mergeMajorType(other.getMajorType());
        }
        if (other.hasNamePart()) {
          mergeNamePart(other.getNamePart());
        }
        if (childBuilder_ == null) {
          if (!other.child_.isEmpty()) {
            if (child_.isEmpty()) {
              child_ = other.child_;
              bitField0_ = (bitField0_ & ~0x00000004);
            } else {
              ensureChildIsMutable();
              child_.addAll(other.child_);
            }
            onChanged();
          }
        } else {
          if (!other.child_.isEmpty()) {
            if (childBuilder_.isEmpty()) {
              childBuilder_.dispose();
              childBuilder_ = null;
              child_ = other.child_;
              bitField0_ = (bitField0_ & ~0x00000004);
              childBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getChildFieldBuilder() : null;
            } else {
              childBuilder_.addAllMessages(other.child_);
            }
          }
        }
        if (other.hasValueCount()) {
          setValueCount(other.getValueCount());
        }
        if (other.hasVarByteLength()) {
          setVarByteLength(other.getVarByteLength());
        }
        if (other.hasBufferLength()) {
          setBufferLength(other.getBufferLength());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        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 {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                input.readMessage(
                    getMajorTypeFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 18: {
                input.readMessage(
                    getNamePartFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              case 26: {
                org.apache.drill.exec.proto.UserBitShared.SerializedField m =
                    input.readMessage(
                        org.apache.drill.exec.proto.UserBitShared.SerializedField.PARSER,
                        extensionRegistry);
                if (childBuilder_ == null) {
                  ensureChildIsMutable();
                  child_.add(m);
                } else {
                  childBuilder_.addMessage(m);
                }
                break;
              } // case 26
              case 32: {
                valueCount_ = input.readInt32();
                bitField0_ |= 0x00000008;
                break;
              } // case 32
              case 40: {
                varByteLength_ = input.readInt32();
                bitField0_ |= 0x00000010;
                break;
              } // case 40
              case 56: {
                bufferLength_ = input.readInt32();
                bitField0_ |= 0x00000020;
                break;
              } // case 56
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private org.apache.drill.common.types.TypeProtos.MajorType majorType_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.common.types.TypeProtos.MajorType, org.apache.drill.common.types.TypeProtos.MajorType.Builder, org.apache.drill.common.types.TypeProtos.MajorTypeOrBuilder> majorTypeBuilder_;
      /**
       * <pre>
       * the type associated with this field.
       * </pre>
       *
       * <code>optional .common.MajorType major_type = 1;</code>
       * @return Whether the majorType field is set.
       */
      public boolean hasMajorType() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <pre>
       * the type associated with this field.
       * </pre>
       *
       * <code>optional .common.MajorType major_type = 1;</code>
       * @return The majorType.
       */
      public org.apache.drill.common.types.TypeProtos.MajorType getMajorType() {
        if (majorTypeBuilder_ == null) {
          return majorType_ == null ? org.apache.drill.common.types.TypeProtos.MajorType.getDefaultInstance() : majorType_;
        } else {
          return majorTypeBuilder_.getMessage();
        }
      }
      /**
       * <pre>
       * the type associated with this field.
       * </pre>
       *
       * <code>optional .common.MajorType major_type = 1;</code>
       */
      public Builder setMajorType(org.apache.drill.common.types.TypeProtos.MajorType value) {
        if (majorTypeBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          majorType_ = value;
          onChanged();
        } else {
          majorTypeBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <pre>
       * the type associated with this field.
       * </pre>
       *
       * <code>optional .common.MajorType major_type = 1;</code>
       */
      public Builder setMajorType(
          org.apache.drill.common.types.TypeProtos.MajorType.Builder builderForValue) {
        if (majorTypeBuilder_ == null) {
          majorType_ = builderForValue.build();
          onChanged();
        } else {
          majorTypeBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <pre>
       * the type associated with this field.
       * </pre>
       *
       * <code>optional .common.MajorType major_type = 1;</code>
       */
      public Builder mergeMajorType(org.apache.drill.common.types.TypeProtos.MajorType value) {
        if (majorTypeBuilder_ == null) {
          if (((bitField0_ & 0x00000001) != 0) &&
              majorType_ != null &&
              majorType_ != org.apache.drill.common.types.TypeProtos.MajorType.getDefaultInstance()) {
            majorType_ =
              org.apache.drill.common.types.TypeProtos.MajorType.newBuilder(majorType_).mergeFrom(value).buildPartial();
          } else {
            majorType_ = value;
          }
          onChanged();
        } else {
          majorTypeBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <pre>
       * the type associated with this field.
       * </pre>
       *
       * <code>optional .common.MajorType major_type = 1;</code>
       */
      public Builder clearMajorType() {
        if (majorTypeBuilder_ == null) {
          majorType_ = null;
          onChanged();
        } else {
          majorTypeBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <pre>
       * the type associated with this field.
       * </pre>
       *
       * <code>optional .common.MajorType major_type = 1;</code>
       */
      public org.apache.drill.common.types.TypeProtos.MajorType.Builder getMajorTypeBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getMajorTypeFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * the type associated with this field.
       * </pre>
       *
       * <code>optional .common.MajorType major_type = 1;</code>
       */
      public org.apache.drill.common.types.TypeProtos.MajorTypeOrBuilder getMajorTypeOrBuilder() {
        if (majorTypeBuilder_ != null) {
          return majorTypeBuilder_.getMessageOrBuilder();
        } else {
          return majorType_ == null ?
              org.apache.drill.common.types.TypeProtos.MajorType.getDefaultInstance() : majorType_;
        }
      }
      /**
       * <pre>
       * the type associated with this field.
       * </pre>
       *
       * <code>optional .common.MajorType major_type = 1;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.common.types.TypeProtos.MajorType, org.apache.drill.common.types.TypeProtos.MajorType.Builder, org.apache.drill.common.types.TypeProtos.MajorTypeOrBuilder> 
          getMajorTypeFieldBuilder() {
        if (majorTypeBuilder_ == null) {
          majorTypeBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.common.types.TypeProtos.MajorType, org.apache.drill.common.types.TypeProtos.MajorType.Builder, org.apache.drill.common.types.TypeProtos.MajorTypeOrBuilder>(
                  getMajorType(),
                  getParentForChildren(),
                  isClean());
          majorType_ = null;
        }
        return majorTypeBuilder_;
      }

      private org.apache.drill.exec.proto.UserBitShared.NamePart namePart_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.NamePart, org.apache.drill.exec.proto.UserBitShared.NamePart.Builder, org.apache.drill.exec.proto.UserBitShared.NamePartOrBuilder> namePartBuilder_;
      /**
       * <code>optional .exec.shared.NamePart name_part = 2;</code>
       * @return Whether the namePart field is set.
       */
      public boolean hasNamePart() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional .exec.shared.NamePart name_part = 2;</code>
       * @return The namePart.
       */
      public org.apache.drill.exec.proto.UserBitShared.NamePart getNamePart() {
        if (namePartBuilder_ == null) {
          return namePart_ == null ? org.apache.drill.exec.proto.UserBitShared.NamePart.getDefaultInstance() : namePart_;
        } else {
          return namePartBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.shared.NamePart name_part = 2;</code>
       */
      public Builder setNamePart(org.apache.drill.exec.proto.UserBitShared.NamePart value) {
        if (namePartBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          namePart_ = value;
          onChanged();
        } else {
          namePartBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.shared.NamePart name_part = 2;</code>
       */
      public Builder setNamePart(
          org.apache.drill.exec.proto.UserBitShared.NamePart.Builder builderForValue) {
        if (namePartBuilder_ == null) {
          namePart_ = builderForValue.build();
          onChanged();
        } else {
          namePartBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.shared.NamePart name_part = 2;</code>
       */
      public Builder mergeNamePart(org.apache.drill.exec.proto.UserBitShared.NamePart value) {
        if (namePartBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0) &&
              namePart_ != null &&
              namePart_ != org.apache.drill.exec.proto.UserBitShared.NamePart.getDefaultInstance()) {
            namePart_ =
              org.apache.drill.exec.proto.UserBitShared.NamePart.newBuilder(namePart_).mergeFrom(value).buildPartial();
          } else {
            namePart_ = value;
          }
          onChanged();
        } else {
          namePartBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.shared.NamePart name_part = 2;</code>
       */
      public Builder clearNamePart() {
        if (namePartBuilder_ == null) {
          namePart_ = null;
          onChanged();
        } else {
          namePartBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>optional .exec.shared.NamePart name_part = 2;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.NamePart.Builder getNamePartBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getNamePartFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.shared.NamePart name_part = 2;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.NamePartOrBuilder getNamePartOrBuilder() {
        if (namePartBuilder_ != null) {
          return namePartBuilder_.getMessageOrBuilder();
        } else {
          return namePart_ == null ?
              org.apache.drill.exec.proto.UserBitShared.NamePart.getDefaultInstance() : namePart_;
        }
      }
      /**
       * <code>optional .exec.shared.NamePart name_part = 2;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.NamePart, org.apache.drill.exec.proto.UserBitShared.NamePart.Builder, org.apache.drill.exec.proto.UserBitShared.NamePartOrBuilder> 
          getNamePartFieldBuilder() {
        if (namePartBuilder_ == null) {
          namePartBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.NamePart, org.apache.drill.exec.proto.UserBitShared.NamePart.Builder, org.apache.drill.exec.proto.UserBitShared.NamePartOrBuilder>(
                  getNamePart(),
                  getParentForChildren(),
                  isClean());
          namePart_ = null;
        }
        return namePartBuilder_;
      }

      private java.util.List<org.apache.drill.exec.proto.UserBitShared.SerializedField> child_ =
        java.util.Collections.emptyList();
      private void ensureChildIsMutable() {
        if (!((bitField0_ & 0x00000004) != 0)) {
          child_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserBitShared.SerializedField>(child_);
          bitField0_ |= 0x00000004;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.SerializedField, org.apache.drill.exec.proto.UserBitShared.SerializedField.Builder, org.apache.drill.exec.proto.UserBitShared.SerializedFieldOrBuilder> childBuilder_;

      /**
       * <pre>
       * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
       * </pre>
       *
       * <code>repeated .exec.shared.SerializedField child = 3;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserBitShared.SerializedField> getChildList() {
        if (childBuilder_ == null) {
          return java.util.Collections.unmodifiableList(child_);
        } else {
          return childBuilder_.getMessageList();
        }
      }
      /**
       * <pre>
       * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
       * </pre>
       *
       * <code>repeated .exec.shared.SerializedField child = 3;</code>
       */
      public int getChildCount() {
        if (childBuilder_ == null) {
          return child_.size();
        } else {
          return childBuilder_.getCount();
        }
      }
      /**
       * <pre>
       * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
       * </pre>
       *
       * <code>repeated .exec.shared.SerializedField child = 3;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.SerializedField getChild(int index) {
        if (childBuilder_ == null) {
          return child_.get(index);
        } else {
          return childBuilder_.getMessage(index);
        }
      }
      /**
       * <pre>
       * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
       * </pre>
       *
       * <code>repeated .exec.shared.SerializedField child = 3;</code>
       */
      public Builder setChild(
          int index, org.apache.drill.exec.proto.UserBitShared.SerializedField value) {
        if (childBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureChildIsMutable();
          child_.set(index, value);
          onChanged();
        } else {
          childBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <pre>
       * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
       * </pre>
       *
       * <code>repeated .exec.shared.SerializedField child = 3;</code>
       */
      public Builder setChild(
          int index, org.apache.drill.exec.proto.UserBitShared.SerializedField.Builder builderForValue) {
        if (childBuilder_ == null) {
          ensureChildIsMutable();
          child_.set(index, builderForValue.build());
          onChanged();
        } else {
          childBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
       * </pre>
       *
       * <code>repeated .exec.shared.SerializedField child = 3;</code>
       */
      public Builder addChild(org.apache.drill.exec.proto.UserBitShared.SerializedField value) {
        if (childBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureChildIsMutable();
          child_.add(value);
          onChanged();
        } else {
          childBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <pre>
       * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
       * </pre>
       *
       * <code>repeated .exec.shared.SerializedField child = 3;</code>
       */
      public Builder addChild(
          int index, org.apache.drill.exec.proto.UserBitShared.SerializedField value) {
        if (childBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureChildIsMutable();
          child_.add(index, value);
          onChanged();
        } else {
          childBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <pre>
       * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
       * </pre>
       *
       * <code>repeated .exec.shared.SerializedField child = 3;</code>
       */
      public Builder addChild(
          org.apache.drill.exec.proto.UserBitShared.SerializedField.Builder builderForValue) {
        if (childBuilder_ == null) {
          ensureChildIsMutable();
          child_.add(builderForValue.build());
          onChanged();
        } else {
          childBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
       * </pre>
       *
       * <code>repeated .exec.shared.SerializedField child = 3;</code>
       */
      public Builder addChild(
          int index, org.apache.drill.exec.proto.UserBitShared.SerializedField.Builder builderForValue) {
        if (childBuilder_ == null) {
          ensureChildIsMutable();
          child_.add(index, builderForValue.build());
          onChanged();
        } else {
          childBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
       * </pre>
       *
       * <code>repeated .exec.shared.SerializedField child = 3;</code>
       */
      public Builder addAllChild(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.UserBitShared.SerializedField> values) {
        if (childBuilder_ == null) {
          ensureChildIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, child_);
          onChanged();
        } else {
          childBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <pre>
       * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
       * </pre>
       *
       * <code>repeated .exec.shared.SerializedField child = 3;</code>
       */
      public Builder clearChild() {
        if (childBuilder_ == null) {
          child_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000004);
          onChanged();
        } else {
          childBuilder_.clear();
        }
        return this;
      }
      /**
       * <pre>
       * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
       * </pre>
       *
       * <code>repeated .exec.shared.SerializedField child = 3;</code>
       */
      public Builder removeChild(int index) {
        if (childBuilder_ == null) {
          ensureChildIsMutable();
          child_.remove(index);
          onChanged();
        } else {
          childBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <pre>
       * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
       * </pre>
       *
       * <code>repeated .exec.shared.SerializedField child = 3;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.SerializedField.Builder getChildBuilder(
          int index) {
        return getChildFieldBuilder().getBuilder(index);
      }
      /**
       * <pre>
       * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
       * </pre>
       *
       * <code>repeated .exec.shared.SerializedField child = 3;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.SerializedFieldOrBuilder getChildOrBuilder(
          int index) {
        if (childBuilder_ == null) {
          return child_.get(index);  } else {
          return childBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <pre>
       * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
       * </pre>
       *
       * <code>repeated .exec.shared.SerializedField child = 3;</code>
       */
      public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.SerializedFieldOrBuilder> 
           getChildOrBuilderList() {
        if (childBuilder_ != null) {
          return childBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(child_);
        }
      }
      /**
       * <pre>
       * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
       * </pre>
       *
       * <code>repeated .exec.shared.SerializedField child = 3;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.SerializedField.Builder addChildBuilder() {
        return getChildFieldBuilder().addBuilder(
            org.apache.drill.exec.proto.UserBitShared.SerializedField.getDefaultInstance());
      }
      /**
       * <pre>
       * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
       * </pre>
       *
       * <code>repeated .exec.shared.SerializedField child = 3;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.SerializedField.Builder addChildBuilder(
          int index) {
        return getChildFieldBuilder().addBuilder(
            index, org.apache.drill.exec.proto.UserBitShared.SerializedField.getDefaultInstance());
      }
      /**
       * <pre>
       * only in the cases of type == MAP or REPEAT_MAP or REPEATED_LIST
       * </pre>
       *
       * <code>repeated .exec.shared.SerializedField child = 3;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserBitShared.SerializedField.Builder> 
           getChildBuilderList() {
        return getChildFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.SerializedField, org.apache.drill.exec.proto.UserBitShared.SerializedField.Builder, org.apache.drill.exec.proto.UserBitShared.SerializedFieldOrBuilder> 
          getChildFieldBuilder() {
        if (childBuilder_ == null) {
          childBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.SerializedField, org.apache.drill.exec.proto.UserBitShared.SerializedField.Builder, org.apache.drill.exec.proto.UserBitShared.SerializedFieldOrBuilder>(
                  child_,
                  ((bitField0_ & 0x00000004) != 0),
                  getParentForChildren(),
                  isClean());
          child_ = null;
        }
        return childBuilder_;
      }

      private int valueCount_ ;
      /**
       * <code>optional int32 value_count = 4;</code>
       * @return Whether the valueCount field is set.
       */
      @java.lang.Override
      public boolean hasValueCount() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <code>optional int32 value_count = 4;</code>
       * @return The valueCount.
       */
      @java.lang.Override
      public int getValueCount() {
        return valueCount_;
      }
      /**
       * <code>optional int32 value_count = 4;</code>
       * @param value The valueCount to set.
       * @return This builder for chaining.
       */
      public Builder setValueCount(int value) {
        bitField0_ |= 0x00000008;
        valueCount_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 value_count = 4;</code>
       * @return This builder for chaining.
       */
      public Builder clearValueCount() {
        bitField0_ = (bitField0_ & ~0x00000008);
        valueCount_ = 0;
        onChanged();
        return this;
      }

      private int varByteLength_ ;
      /**
       * <code>optional int32 var_byte_length = 5;</code>
       * @return Whether the varByteLength field is set.
       */
      @java.lang.Override
      public boolean hasVarByteLength() {
        return ((bitField0_ & 0x00000010) != 0);
      }
      /**
       * <code>optional int32 var_byte_length = 5;</code>
       * @return The varByteLength.
       */
      @java.lang.Override
      public int getVarByteLength() {
        return varByteLength_;
      }
      /**
       * <code>optional int32 var_byte_length = 5;</code>
       * @param value The varByteLength to set.
       * @return This builder for chaining.
       */
      public Builder setVarByteLength(int value) {
        bitField0_ |= 0x00000010;
        varByteLength_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 var_byte_length = 5;</code>
       * @return This builder for chaining.
       */
      public Builder clearVarByteLength() {
        bitField0_ = (bitField0_ & ~0x00000010);
        varByteLength_ = 0;
        onChanged();
        return this;
      }

      private int bufferLength_ ;
      /**
       * <code>optional int32 buffer_length = 7;</code>
       * @return Whether the bufferLength field is set.
       */
      @java.lang.Override
      public boolean hasBufferLength() {
        return ((bitField0_ & 0x00000020) != 0);
      }
      /**
       * <code>optional int32 buffer_length = 7;</code>
       * @return The bufferLength.
       */
      @java.lang.Override
      public int getBufferLength() {
        return bufferLength_;
      }
      /**
       * <code>optional int32 buffer_length = 7;</code>
       * @param value The bufferLength to set.
       * @return This builder for chaining.
       */
      public Builder setBufferLength(int value) {
        bitField0_ |= 0x00000020;
        bufferLength_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 buffer_length = 7;</code>
       * @return This builder for chaining.
       */
      public Builder clearBufferLength() {
        bitField0_ = (bitField0_ & ~0x00000020);
        bufferLength_ = 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:exec.shared.SerializedField)
    }

    // @@protoc_insertion_point(class_scope:exec.shared.SerializedField)
    private static final org.apache.drill.exec.proto.UserBitShared.SerializedField DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserBitShared.SerializedField();
    }

    public static org.apache.drill.exec.proto.UserBitShared.SerializedField getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<SerializedField>
        PARSER = new com.google.protobuf.AbstractParser<SerializedField>() {
      @java.lang.Override
      public SerializedField parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

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

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

    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.SerializedField getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface NodeStatusOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.shared.NodeStatus)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional int32 node_id = 1;</code>
     * @return Whether the nodeId field is set.
     */
    boolean hasNodeId();
    /**
     * <code>optional int32 node_id = 1;</code>
     * @return The nodeId.
     */
    int getNodeId();

    /**
     * <code>optional int64 memory_footprint = 2;</code>
     * @return Whether the memoryFootprint field is set.
     */
    boolean hasMemoryFootprint();
    /**
     * <code>optional int64 memory_footprint = 2;</code>
     * @return The memoryFootprint.
     */
    long getMemoryFootprint();
  }
  /**
   * Protobuf type {@code exec.shared.NodeStatus}
   */
  public static final class NodeStatus extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.NodeStatus)
      NodeStatusOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use NodeStatus.newBuilder() to construct.
    private NodeStatus(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private NodeStatus() {
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new NodeStatus();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_NodeStatus_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_NodeStatus_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserBitShared.NodeStatus.class, org.apache.drill.exec.proto.UserBitShared.NodeStatus.Builder.class);
    }

    private int bitField0_;
    public static final int NODE_ID_FIELD_NUMBER = 1;
    private int nodeId_;
    /**
     * <code>optional int32 node_id = 1;</code>
     * @return Whether the nodeId field is set.
     */
    @java.lang.Override
    public boolean hasNodeId() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional int32 node_id = 1;</code>
     * @return The nodeId.
     */
    @java.lang.Override
    public int getNodeId() {
      return nodeId_;
    }

    public static final int MEMORY_FOOTPRINT_FIELD_NUMBER = 2;
    private long memoryFootprint_;
    /**
     * <code>optional int64 memory_footprint = 2;</code>
     * @return Whether the memoryFootprint field is set.
     */
    @java.lang.Override
    public boolean hasMemoryFootprint() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional int64 memory_footprint = 2;</code>
     * @return The memoryFootprint.
     */
    @java.lang.Override
    public long getMemoryFootprint() {
      return memoryFootprint_;
    }

    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 (((bitField0_ & 0x00000001) != 0)) {
        output.writeInt32(1, nodeId_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeInt64(2, memoryFootprint_);
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(1, nodeId_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, memoryFootprint_);
      }
      size += getUnknownFields().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.drill.exec.proto.UserBitShared.NodeStatus)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserBitShared.NodeStatus other = (org.apache.drill.exec.proto.UserBitShared.NodeStatus) obj;

      if (hasNodeId() != other.hasNodeId()) return false;
      if (hasNodeId()) {
        if (getNodeId()
            != other.getNodeId()) return false;
      }
      if (hasMemoryFootprint() != other.hasMemoryFootprint()) return false;
      if (hasMemoryFootprint()) {
        if (getMemoryFootprint()
            != other.getMemoryFootprint()) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasNodeId()) {
        hash = (37 * hash) + NODE_ID_FIELD_NUMBER;
        hash = (53 * hash) + getNodeId();
      }
      if (hasMemoryFootprint()) {
        hash = (37 * hash) + MEMORY_FOOTPRINT_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getMemoryFootprint());
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserBitShared.NodeStatus parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.NodeStatus parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.NodeStatus parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.NodeStatus 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.drill.exec.proto.UserBitShared.NodeStatus parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.NodeStatus parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.NodeStatus parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.NodeStatus 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.drill.exec.proto.UserBitShared.NodeStatus parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.NodeStatus 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.drill.exec.proto.UserBitShared.NodeStatus parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.NodeStatus 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.drill.exec.proto.UserBitShared.NodeStatus 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 exec.shared.NodeStatus}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.shared.NodeStatus)
        org.apache.drill.exec.proto.UserBitShared.NodeStatusOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_NodeStatus_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_NodeStatus_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserBitShared.NodeStatus.class, org.apache.drill.exec.proto.UserBitShared.NodeStatus.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserBitShared.NodeStatus.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        nodeId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        memoryFootprint_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_NodeStatus_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.NodeStatus getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserBitShared.NodeStatus.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.NodeStatus build() {
        org.apache.drill.exec.proto.UserBitShared.NodeStatus result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.NodeStatus buildPartial() {
        org.apache.drill.exec.proto.UserBitShared.NodeStatus result = new org.apache.drill.exec.proto.UserBitShared.NodeStatus(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.nodeId_ = nodeId_;
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.memoryFootprint_ = memoryFootprint_;
          to_bitField0_ |= 0x00000002;
        }
        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.drill.exec.proto.UserBitShared.NodeStatus) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.NodeStatus)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.NodeStatus other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.NodeStatus.getDefaultInstance()) return this;
        if (other.hasNodeId()) {
          setNodeId(other.getNodeId());
        }
        if (other.hasMemoryFootprint()) {
          setMemoryFootprint(other.getMemoryFootprint());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        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 {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                nodeId_ = input.readInt32();
                bitField0_ |= 0x00000001;
                break;
              } // case 8
              case 16: {
                memoryFootprint_ = input.readInt64();
                bitField0_ |= 0x00000002;
                break;
              } // case 16
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private int nodeId_ ;
      /**
       * <code>optional int32 node_id = 1;</code>
       * @return Whether the nodeId field is set.
       */
      @java.lang.Override
      public boolean hasNodeId() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional int32 node_id = 1;</code>
       * @return The nodeId.
       */
      @java.lang.Override
      public int getNodeId() {
        return nodeId_;
      }
      /**
       * <code>optional int32 node_id = 1;</code>
       * @param value The nodeId to set.
       * @return This builder for chaining.
       */
      public Builder setNodeId(int value) {
        bitField0_ |= 0x00000001;
        nodeId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 node_id = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearNodeId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        nodeId_ = 0;
        onChanged();
        return this;
      }

      private long memoryFootprint_ ;
      /**
       * <code>optional int64 memory_footprint = 2;</code>
       * @return Whether the memoryFootprint field is set.
       */
      @java.lang.Override
      public boolean hasMemoryFootprint() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional int64 memory_footprint = 2;</code>
       * @return The memoryFootprint.
       */
      @java.lang.Override
      public long getMemoryFootprint() {
        return memoryFootprint_;
      }
      /**
       * <code>optional int64 memory_footprint = 2;</code>
       * @param value The memoryFootprint to set.
       * @return This builder for chaining.
       */
      public Builder setMemoryFootprint(long value) {
        bitField0_ |= 0x00000002;
        memoryFootprint_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 memory_footprint = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearMemoryFootprint() {
        bitField0_ = (bitField0_ & ~0x00000002);
        memoryFootprint_ = 0L;
        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:exec.shared.NodeStatus)
    }

    // @@protoc_insertion_point(class_scope:exec.shared.NodeStatus)
    private static final org.apache.drill.exec.proto.UserBitShared.NodeStatus DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserBitShared.NodeStatus();
    }

    public static org.apache.drill.exec.proto.UserBitShared.NodeStatus getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<NodeStatus>
        PARSER = new com.google.protobuf.AbstractParser<NodeStatus>() {
      @java.lang.Override
      public NodeStatus parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

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

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

    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.NodeStatus getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface QueryResultOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.shared.QueryResult)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional .exec.shared.QueryResult.QueryState query_state = 1;</code>
     * @return Whether the queryState field is set.
     */
    boolean hasQueryState();
    /**
     * <code>optional .exec.shared.QueryResult.QueryState query_state = 1;</code>
     * @return The queryState.
     */
    org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState getQueryState();

    /**
     * <code>optional .exec.shared.QueryId query_id = 2;</code>
     * @return Whether the queryId field is set.
     */
    boolean hasQueryId();
    /**
     * <code>optional .exec.shared.QueryId query_id = 2;</code>
     * @return The queryId.
     */
    org.apache.drill.exec.proto.UserBitShared.QueryId getQueryId();
    /**
     * <code>optional .exec.shared.QueryId query_id = 2;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder getQueryIdOrBuilder();

    /**
     * <code>repeated .exec.shared.DrillPBError error = 3;</code>
     */
    java.util.List<org.apache.drill.exec.proto.UserBitShared.DrillPBError> 
        getErrorList();
    /**
     * <code>repeated .exec.shared.DrillPBError error = 3;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.DrillPBError getError(int index);
    /**
     * <code>repeated .exec.shared.DrillPBError error = 3;</code>
     */
    int getErrorCount();
    /**
     * <code>repeated .exec.shared.DrillPBError error = 3;</code>
     */
    java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder> 
        getErrorOrBuilderList();
    /**
     * <code>repeated .exec.shared.DrillPBError error = 3;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder(
        int index);
  }
  /**
   * <pre>
   * Used by the server to report informations about the query state to the client
   * </pre>
   *
   * Protobuf type {@code exec.shared.QueryResult}
   */
  public static final class QueryResult extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.QueryResult)
      QueryResultOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use QueryResult.newBuilder() to construct.
    private QueryResult(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private QueryResult() {
      queryState_ = 0;
      error_ = java.util.Collections.emptyList();
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new QueryResult();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_QueryResult_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_QueryResult_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserBitShared.QueryResult.class, org.apache.drill.exec.proto.UserBitShared.QueryResult.Builder.class);
    }

    /**
     * Protobuf enum {@code exec.shared.QueryResult.QueryState}
     */
    public enum QueryState
        implements com.google.protobuf.ProtocolMessageEnum {
      /**
       * <pre>
       * query has been scheduled for execution. This is post-enqueued.
       * </pre>
       *
       * <code>STARTING = 0;</code>
       */
      STARTING(0),
      /**
       * <code>RUNNING = 1;</code>
       */
      RUNNING(1),
      /**
       * <pre>
       * query has completed successfully
       * </pre>
       *
       * <code>COMPLETED = 2;</code>
       */
      COMPLETED(2),
      /**
       * <pre>
       * query has been cancelled, and all cleanup is complete
       * </pre>
       *
       * <code>CANCELED = 3;</code>
       */
      CANCELED(3),
      /**
       * <code>FAILED = 4;</code>
       */
      FAILED(4),
      /**
       * <pre>
       * cancellation has been requested, and is being processed
       * </pre>
       *
       * <code>CANCELLATION_REQUESTED = 5;</code>
       */
      CANCELLATION_REQUESTED(5),
      /**
       * <pre>
       * query has been enqueued. this is pre-starting.
       * </pre>
       *
       * <code>ENQUEUED = 6;</code>
       */
      ENQUEUED(6),
      /**
       * <pre>
       * query is at preparation stage, foreman is initializing
       * </pre>
       *
       * <code>PREPARING = 7;</code>
       */
      PREPARING(7),
      /**
       * <pre>
       * query is at planning stage (includes logical or / and physical planning)
       * </pre>
       *
       * <code>PLANNING = 8;</code>
       */
      PLANNING(8),
      ;

      /**
       * <pre>
       * query has been scheduled for execution. This is post-enqueued.
       * </pre>
       *
       * <code>STARTING = 0;</code>
       */
      public static final int STARTING_VALUE = 0;
      /**
       * <code>RUNNING = 1;</code>
       */
      public static final int RUNNING_VALUE = 1;
      /**
       * <pre>
       * query has completed successfully
       * </pre>
       *
       * <code>COMPLETED = 2;</code>
       */
      public static final int COMPLETED_VALUE = 2;
      /**
       * <pre>
       * query has been cancelled, and all cleanup is complete
       * </pre>
       *
       * <code>CANCELED = 3;</code>
       */
      public static final int CANCELED_VALUE = 3;
      /**
       * <code>FAILED = 4;</code>
       */
      public static final int FAILED_VALUE = 4;
      /**
       * <pre>
       * cancellation has been requested, and is being processed
       * </pre>
       *
       * <code>CANCELLATION_REQUESTED = 5;</code>
       */
      public static final int CANCELLATION_REQUESTED_VALUE = 5;
      /**
       * <pre>
       * query has been enqueued. this is pre-starting.
       * </pre>
       *
       * <code>ENQUEUED = 6;</code>
       */
      public static final int ENQUEUED_VALUE = 6;
      /**
       * <pre>
       * query is at preparation stage, foreman is initializing
       * </pre>
       *
       * <code>PREPARING = 7;</code>
       */
      public static final int PREPARING_VALUE = 7;
      /**
       * <pre>
       * query is at planning stage (includes logical or / and physical planning)
       * </pre>
       *
       * <code>PLANNING = 8;</code>
       */
      public static final int PLANNING_VALUE = 8;


      public final int getNumber() {
        return value;
      }

      /**
       * @param value The numeric wire value of the corresponding enum entry.
       * @return The enum associated with the given numeric wire value.
       * @deprecated Use {@link #forNumber(int)} instead.
       */
      @java.lang.Deprecated
      public static QueryState valueOf(int value) {
        return forNumber(value);
      }

      /**
       * @param value The numeric wire value of the corresponding enum entry.
       * @return The enum associated with the given numeric wire value.
       */
      public static QueryState forNumber(int value) {
        switch (value) {
          case 0: return STARTING;
          case 1: return RUNNING;
          case 2: return COMPLETED;
          case 3: return CANCELED;
          case 4: return FAILED;
          case 5: return CANCELLATION_REQUESTED;
          case 6: return ENQUEUED;
          case 7: return PREPARING;
          case 8: return PLANNING;
          default: return null;
        }
      }

      public static com.google.protobuf.Internal.EnumLiteMap<QueryState>
          internalGetValueMap() {
        return internalValueMap;
      }
      private static final com.google.protobuf.Internal.EnumLiteMap<
          QueryState> internalValueMap =
            new com.google.protobuf.Internal.EnumLiteMap<QueryState>() {
              public QueryState findValueByNumber(int number) {
                return QueryState.forNumber(number);
              }
            };

      public final com.google.protobuf.Descriptors.EnumValueDescriptor
          getValueDescriptor() {
        return getDescriptor().getValues().get(ordinal());
      }
      public final com.google.protobuf.Descriptors.EnumDescriptor
          getDescriptorForType() {
        return getDescriptor();
      }
      public static final com.google.protobuf.Descriptors.EnumDescriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserBitShared.QueryResult.getDescriptor().getEnumTypes().get(0);
      }

      private static final QueryState[] VALUES = values();

      public static QueryState valueOf(
          com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
        if (desc.getType() != getDescriptor()) {
          throw new java.lang.IllegalArgumentException(
            "EnumValueDescriptor is not for this type.");
        }
        return VALUES[desc.getIndex()];
      }

      private final int value;

      private QueryState(int value) {
        this.value = value;
      }

      // @@protoc_insertion_point(enum_scope:exec.shared.QueryResult.QueryState)
    }

    private int bitField0_;
    public static final int QUERY_STATE_FIELD_NUMBER = 1;
    private int queryState_;
    /**
     * <code>optional .exec.shared.QueryResult.QueryState query_state = 1;</code>
     * @return Whether the queryState field is set.
     */
    @java.lang.Override public boolean hasQueryState() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional .exec.shared.QueryResult.QueryState query_state = 1;</code>
     * @return The queryState.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState getQueryState() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState result = org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.valueOf(queryState_);
      return result == null ? org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.STARTING : result;
    }

    public static final int QUERY_ID_FIELD_NUMBER = 2;
    private org.apache.drill.exec.proto.UserBitShared.QueryId queryId_;
    /**
     * <code>optional .exec.shared.QueryId query_id = 2;</code>
     * @return Whether the queryId field is set.
     */
    @java.lang.Override
    public boolean hasQueryId() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .exec.shared.QueryId query_id = 2;</code>
     * @return The queryId.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.QueryId getQueryId() {
      return queryId_ == null ? org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance() : queryId_;
    }
    /**
     * <code>optional .exec.shared.QueryId query_id = 2;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder getQueryIdOrBuilder() {
      return queryId_ == null ? org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance() : queryId_;
    }

    public static final int ERROR_FIELD_NUMBER = 3;
    private java.util.List<org.apache.drill.exec.proto.UserBitShared.DrillPBError> error_;
    /**
     * <code>repeated .exec.shared.DrillPBError error = 3;</code>
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.UserBitShared.DrillPBError> getErrorList() {
      return error_;
    }
    /**
     * <code>repeated .exec.shared.DrillPBError error = 3;</code>
     */
    @java.lang.Override
    public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder> 
        getErrorOrBuilderList() {
      return error_;
    }
    /**
     * <code>repeated .exec.shared.DrillPBError error = 3;</code>
     */
    @java.lang.Override
    public int getErrorCount() {
      return error_.size();
    }
    /**
     * <code>repeated .exec.shared.DrillPBError error = 3;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.DrillPBError getError(int index) {
      return error_.get(index);
    }
    /**
     * <code>repeated .exec.shared.DrillPBError error = 3;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder(
        int index) {
      return error_.get(index);
    }

    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 (((bitField0_ & 0x00000001) != 0)) {
        output.writeEnum(1, queryState_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeMessage(2, getQueryId());
      }
      for (int i = 0; i < error_.size(); i++) {
        output.writeMessage(3, error_.get(i));
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(1, queryState_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, getQueryId());
      }
      for (int i = 0; i < error_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, error_.get(i));
      }
      size += getUnknownFields().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.drill.exec.proto.UserBitShared.QueryResult)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserBitShared.QueryResult other = (org.apache.drill.exec.proto.UserBitShared.QueryResult) obj;

      if (hasQueryState() != other.hasQueryState()) return false;
      if (hasQueryState()) {
        if (queryState_ != other.queryState_) return false;
      }
      if (hasQueryId() != other.hasQueryId()) return false;
      if (hasQueryId()) {
        if (!getQueryId()
            .equals(other.getQueryId())) return false;
      }
      if (!getErrorList()
          .equals(other.getErrorList())) return false;
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasQueryState()) {
        hash = (37 * hash) + QUERY_STATE_FIELD_NUMBER;
        hash = (53 * hash) + queryState_;
      }
      if (hasQueryId()) {
        hash = (37 * hash) + QUERY_ID_FIELD_NUMBER;
        hash = (53 * hash) + getQueryId().hashCode();
      }
      if (getErrorCount() > 0) {
        hash = (37 * hash) + ERROR_FIELD_NUMBER;
        hash = (53 * hash) + getErrorList().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserBitShared.QueryResult parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryResult parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryResult parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryResult 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.drill.exec.proto.UserBitShared.QueryResult parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryResult parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryResult parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryResult 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.drill.exec.proto.UserBitShared.QueryResult parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryResult 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.drill.exec.proto.UserBitShared.QueryResult parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryResult 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.drill.exec.proto.UserBitShared.QueryResult 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>
     * Used by the server to report informations about the query state to the client
     * </pre>
     *
     * Protobuf type {@code exec.shared.QueryResult}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.shared.QueryResult)
        org.apache.drill.exec.proto.UserBitShared.QueryResultOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_QueryResult_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_QueryResult_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserBitShared.QueryResult.class, org.apache.drill.exec.proto.UserBitShared.QueryResult.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserBitShared.QueryResult.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getQueryIdFieldBuilder();
          getErrorFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        queryState_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        if (queryIdBuilder_ == null) {
          queryId_ = null;
        } else {
          queryIdBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        if (errorBuilder_ == null) {
          error_ = java.util.Collections.emptyList();
        } else {
          error_ = null;
          errorBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_QueryResult_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.QueryResult getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserBitShared.QueryResult.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.QueryResult build() {
        org.apache.drill.exec.proto.UserBitShared.QueryResult result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.QueryResult buildPartial() {
        org.apache.drill.exec.proto.UserBitShared.QueryResult result = new org.apache.drill.exec.proto.UserBitShared.QueryResult(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.queryState_ = queryState_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          if (queryIdBuilder_ == null) {
            result.queryId_ = queryId_;
          } else {
            result.queryId_ = queryIdBuilder_.build();
          }
          to_bitField0_ |= 0x00000002;
        }
        if (errorBuilder_ == null) {
          if (((bitField0_ & 0x00000004) != 0)) {
            error_ = java.util.Collections.unmodifiableList(error_);
            bitField0_ = (bitField0_ & ~0x00000004);
          }
          result.error_ = error_;
        } else {
          result.error_ = errorBuilder_.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.drill.exec.proto.UserBitShared.QueryResult) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.QueryResult)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.QueryResult other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.QueryResult.getDefaultInstance()) return this;
        if (other.hasQueryState()) {
          setQueryState(other.getQueryState());
        }
        if (other.hasQueryId()) {
          mergeQueryId(other.getQueryId());
        }
        if (errorBuilder_ == null) {
          if (!other.error_.isEmpty()) {
            if (error_.isEmpty()) {
              error_ = other.error_;
              bitField0_ = (bitField0_ & ~0x00000004);
            } else {
              ensureErrorIsMutable();
              error_.addAll(other.error_);
            }
            onChanged();
          }
        } else {
          if (!other.error_.isEmpty()) {
            if (errorBuilder_.isEmpty()) {
              errorBuilder_.dispose();
              errorBuilder_ = null;
              error_ = other.error_;
              bitField0_ = (bitField0_ & ~0x00000004);
              errorBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getErrorFieldBuilder() : null;
            } else {
              errorBuilder_.addAllMessages(other.error_);
            }
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        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 {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState tmpValue =
                    org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(1, tmpRaw);
                } else {
                  queryState_ = tmpRaw;
                  bitField0_ |= 0x00000001;
                }
                break;
              } // case 8
              case 18: {
                input.readMessage(
                    getQueryIdFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              case 26: {
                org.apache.drill.exec.proto.UserBitShared.DrillPBError m =
                    input.readMessage(
                        org.apache.drill.exec.proto.UserBitShared.DrillPBError.PARSER,
                        extensionRegistry);
                if (errorBuilder_ == null) {
                  ensureErrorIsMutable();
                  error_.add(m);
                } else {
                  errorBuilder_.addMessage(m);
                }
                break;
              } // case 26
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private int queryState_ = 0;
      /**
       * <code>optional .exec.shared.QueryResult.QueryState query_state = 1;</code>
       * @return Whether the queryState field is set.
       */
      @java.lang.Override public boolean hasQueryState() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .exec.shared.QueryResult.QueryState query_state = 1;</code>
       * @return The queryState.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState getQueryState() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState result = org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.valueOf(queryState_);
        return result == null ? org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.STARTING : result;
      }
      /**
       * <code>optional .exec.shared.QueryResult.QueryState query_state = 1;</code>
       * @param value The queryState to set.
       * @return This builder for chaining.
       */
      public Builder setQueryState(org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000001;
        queryState_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryResult.QueryState query_state = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearQueryState() {
        bitField0_ = (bitField0_ & ~0x00000001);
        queryState_ = 0;
        onChanged();
        return this;
      }

      private org.apache.drill.exec.proto.UserBitShared.QueryId queryId_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.QueryId, org.apache.drill.exec.proto.UserBitShared.QueryId.Builder, org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder> queryIdBuilder_;
      /**
       * <code>optional .exec.shared.QueryId query_id = 2;</code>
       * @return Whether the queryId field is set.
       */
      public boolean hasQueryId() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 2;</code>
       * @return The queryId.
       */
      public org.apache.drill.exec.proto.UserBitShared.QueryId getQueryId() {
        if (queryIdBuilder_ == null) {
          return queryId_ == null ? org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance() : queryId_;
        } else {
          return queryIdBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 2;</code>
       */
      public Builder setQueryId(org.apache.drill.exec.proto.UserBitShared.QueryId value) {
        if (queryIdBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          queryId_ = value;
          onChanged();
        } else {
          queryIdBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 2;</code>
       */
      public Builder setQueryId(
          org.apache.drill.exec.proto.UserBitShared.QueryId.Builder builderForValue) {
        if (queryIdBuilder_ == null) {
          queryId_ = builderForValue.build();
          onChanged();
        } else {
          queryIdBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 2;</code>
       */
      public Builder mergeQueryId(org.apache.drill.exec.proto.UserBitShared.QueryId value) {
        if (queryIdBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0) &&
              queryId_ != null &&
              queryId_ != org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance()) {
            queryId_ =
              org.apache.drill.exec.proto.UserBitShared.QueryId.newBuilder(queryId_).mergeFrom(value).buildPartial();
          } else {
            queryId_ = value;
          }
          onChanged();
        } else {
          queryIdBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 2;</code>
       */
      public Builder clearQueryId() {
        if (queryIdBuilder_ == null) {
          queryId_ = null;
          onChanged();
        } else {
          queryIdBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 2;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.QueryId.Builder getQueryIdBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getQueryIdFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 2;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder getQueryIdOrBuilder() {
        if (queryIdBuilder_ != null) {
          return queryIdBuilder_.getMessageOrBuilder();
        } else {
          return queryId_ == null ?
              org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance() : queryId_;
        }
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 2;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.QueryId, org.apache.drill.exec.proto.UserBitShared.QueryId.Builder, org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder> 
          getQueryIdFieldBuilder() {
        if (queryIdBuilder_ == null) {
          queryIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.QueryId, org.apache.drill.exec.proto.UserBitShared.QueryId.Builder, org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder>(
                  getQueryId(),
                  getParentForChildren(),
                  isClean());
          queryId_ = null;
        }
        return queryIdBuilder_;
      }

      private java.util.List<org.apache.drill.exec.proto.UserBitShared.DrillPBError> error_ =
        java.util.Collections.emptyList();
      private void ensureErrorIsMutable() {
        if (!((bitField0_ & 0x00000004) != 0)) {
          error_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserBitShared.DrillPBError>(error_);
          bitField0_ |= 0x00000004;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder> errorBuilder_;

      /**
       * <code>repeated .exec.shared.DrillPBError error = 3;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserBitShared.DrillPBError> getErrorList() {
        if (errorBuilder_ == null) {
          return java.util.Collections.unmodifiableList(error_);
        } else {
          return errorBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .exec.shared.DrillPBError error = 3;</code>
       */
      public int getErrorCount() {
        if (errorBuilder_ == null) {
          return error_.size();
        } else {
          return errorBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .exec.shared.DrillPBError error = 3;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBError getError(int index) {
        if (errorBuilder_ == null) {
          return error_.get(index);
        } else {
          return errorBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder setError(
          int index, org.apache.drill.exec.proto.UserBitShared.DrillPBError value) {
        if (errorBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureErrorIsMutable();
          error_.set(index, value);
          onChanged();
        } else {
          errorBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder setError(
          int index, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder builderForValue) {
        if (errorBuilder_ == null) {
          ensureErrorIsMutable();
          error_.set(index, builderForValue.build());
          onChanged();
        } else {
          errorBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder addError(org.apache.drill.exec.proto.UserBitShared.DrillPBError value) {
        if (errorBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureErrorIsMutable();
          error_.add(value);
          onChanged();
        } else {
          errorBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder addError(
          int index, org.apache.drill.exec.proto.UserBitShared.DrillPBError value) {
        if (errorBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureErrorIsMutable();
          error_.add(index, value);
          onChanged();
        } else {
          errorBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder addError(
          org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder builderForValue) {
        if (errorBuilder_ == null) {
          ensureErrorIsMutable();
          error_.add(builderForValue.build());
          onChanged();
        } else {
          errorBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder addError(
          int index, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder builderForValue) {
        if (errorBuilder_ == null) {
          ensureErrorIsMutable();
          error_.add(index, builderForValue.build());
          onChanged();
        } else {
          errorBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder addAllError(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.UserBitShared.DrillPBError> values) {
        if (errorBuilder_ == null) {
          ensureErrorIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, error_);
          onChanged();
        } else {
          errorBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder clearError() {
        if (errorBuilder_ == null) {
          error_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000004);
          onChanged();
        } else {
          errorBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder removeError(int index) {
        if (errorBuilder_ == null) {
          ensureErrorIsMutable();
          error_.remove(index);
          onChanged();
        } else {
          errorBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.DrillPBError error = 3;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder getErrorBuilder(
          int index) {
        return getErrorFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .exec.shared.DrillPBError error = 3;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder(
          int index) {
        if (errorBuilder_ == null) {
          return error_.get(index);  } else {
          return errorBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .exec.shared.DrillPBError error = 3;</code>
       */
      public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder> 
           getErrorOrBuilderList() {
        if (errorBuilder_ != null) {
          return errorBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(error_);
        }
      }
      /**
       * <code>repeated .exec.shared.DrillPBError error = 3;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder addErrorBuilder() {
        return getErrorFieldBuilder().addBuilder(
            org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.shared.DrillPBError error = 3;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder addErrorBuilder(
          int index) {
        return getErrorFieldBuilder().addBuilder(
            index, org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.shared.DrillPBError error = 3;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder> 
           getErrorBuilderList() {
        return getErrorFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder> 
          getErrorFieldBuilder() {
        if (errorBuilder_ == null) {
          errorBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder>(
                  error_,
                  ((bitField0_ & 0x00000004) != 0),
                  getParentForChildren(),
                  isClean());
          error_ = null;
        }
        return errorBuilder_;
      }
      @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:exec.shared.QueryResult)
    }

    // @@protoc_insertion_point(class_scope:exec.shared.QueryResult)
    private static final org.apache.drill.exec.proto.UserBitShared.QueryResult DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserBitShared.QueryResult();
    }

    public static org.apache.drill.exec.proto.UserBitShared.QueryResult getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<QueryResult>
        PARSER = new com.google.protobuf.AbstractParser<QueryResult>() {
      @java.lang.Override
      public QueryResult parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

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

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

    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.QueryResult getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface QueryDataOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.shared.QueryData)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional .exec.shared.QueryId query_id = 1;</code>
     * @return Whether the queryId field is set.
     */
    boolean hasQueryId();
    /**
     * <code>optional .exec.shared.QueryId query_id = 1;</code>
     * @return The queryId.
     */
    org.apache.drill.exec.proto.UserBitShared.QueryId getQueryId();
    /**
     * <code>optional .exec.shared.QueryId query_id = 1;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder getQueryIdOrBuilder();

    /**
     * <code>optional int32 row_count = 2;</code>
     * @return Whether the rowCount field is set.
     */
    boolean hasRowCount();
    /**
     * <code>optional int32 row_count = 2;</code>
     * @return The rowCount.
     */
    int getRowCount();

    /**
     * <code>optional .exec.shared.RecordBatchDef def = 3;</code>
     * @return Whether the def field is set.
     */
    boolean hasDef();
    /**
     * <code>optional .exec.shared.RecordBatchDef def = 3;</code>
     * @return The def.
     */
    org.apache.drill.exec.proto.UserBitShared.RecordBatchDef getDef();
    /**
     * <code>optional .exec.shared.RecordBatchDef def = 3;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.RecordBatchDefOrBuilder getDefOrBuilder();

    /**
     * <code>optional int32 affected_rows_count = 4;</code>
     * @return Whether the affectedRowsCount field is set.
     */
    boolean hasAffectedRowsCount();
    /**
     * <code>optional int32 affected_rows_count = 4;</code>
     * @return The affectedRowsCount.
     */
    int getAffectedRowsCount();
  }
  /**
   * <pre>
   * Used by the server when sending query result data batches to the client
   * </pre>
   *
   * Protobuf type {@code exec.shared.QueryData}
   */
  public static final class QueryData extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.QueryData)
      QueryDataOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use QueryData.newBuilder() to construct.
    private QueryData(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private QueryData() {
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new QueryData();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_QueryData_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_QueryData_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserBitShared.QueryData.class, org.apache.drill.exec.proto.UserBitShared.QueryData.Builder.class);
    }

    private int bitField0_;
    public static final int QUERY_ID_FIELD_NUMBER = 1;
    private org.apache.drill.exec.proto.UserBitShared.QueryId queryId_;
    /**
     * <code>optional .exec.shared.QueryId query_id = 1;</code>
     * @return Whether the queryId field is set.
     */
    @java.lang.Override
    public boolean hasQueryId() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional .exec.shared.QueryId query_id = 1;</code>
     * @return The queryId.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.QueryId getQueryId() {
      return queryId_ == null ? org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance() : queryId_;
    }
    /**
     * <code>optional .exec.shared.QueryId query_id = 1;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder getQueryIdOrBuilder() {
      return queryId_ == null ? org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance() : queryId_;
    }

    public static final int ROW_COUNT_FIELD_NUMBER = 2;
    private int rowCount_;
    /**
     * <code>optional int32 row_count = 2;</code>
     * @return Whether the rowCount field is set.
     */
    @java.lang.Override
    public boolean hasRowCount() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional int32 row_count = 2;</code>
     * @return The rowCount.
     */
    @java.lang.Override
    public int getRowCount() {
      return rowCount_;
    }

    public static final int DEF_FIELD_NUMBER = 3;
    private org.apache.drill.exec.proto.UserBitShared.RecordBatchDef def_;
    /**
     * <code>optional .exec.shared.RecordBatchDef def = 3;</code>
     * @return Whether the def field is set.
     */
    @java.lang.Override
    public boolean hasDef() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional .exec.shared.RecordBatchDef def = 3;</code>
     * @return The def.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.RecordBatchDef getDef() {
      return def_ == null ? org.apache.drill.exec.proto.UserBitShared.RecordBatchDef.getDefaultInstance() : def_;
    }
    /**
     * <code>optional .exec.shared.RecordBatchDef def = 3;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.RecordBatchDefOrBuilder getDefOrBuilder() {
      return def_ == null ? org.apache.drill.exec.proto.UserBitShared.RecordBatchDef.getDefaultInstance() : def_;
    }

    public static final int AFFECTED_ROWS_COUNT_FIELD_NUMBER = 4;
    private int affectedRowsCount_;
    /**
     * <code>optional int32 affected_rows_count = 4;</code>
     * @return Whether the affectedRowsCount field is set.
     */
    @java.lang.Override
    public boolean hasAffectedRowsCount() {
      return ((bitField0_ & 0x00000008) != 0);
    }
    /**
     * <code>optional int32 affected_rows_count = 4;</code>
     * @return The affectedRowsCount.
     */
    @java.lang.Override
    public int getAffectedRowsCount() {
      return affectedRowsCount_;
    }

    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 (((bitField0_ & 0x00000001) != 0)) {
        output.writeMessage(1, getQueryId());
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeInt32(2, rowCount_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeMessage(3, getDef());
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        output.writeInt32(4, affectedRowsCount_);
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, getQueryId());
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(2, rowCount_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, getDef());
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(4, affectedRowsCount_);
      }
      size += getUnknownFields().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.drill.exec.proto.UserBitShared.QueryData)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserBitShared.QueryData other = (org.apache.drill.exec.proto.UserBitShared.QueryData) obj;

      if (hasQueryId() != other.hasQueryId()) return false;
      if (hasQueryId()) {
        if (!getQueryId()
            .equals(other.getQueryId())) return false;
      }
      if (hasRowCount() != other.hasRowCount()) return false;
      if (hasRowCount()) {
        if (getRowCount()
            != other.getRowCount()) return false;
      }
      if (hasDef() != other.hasDef()) return false;
      if (hasDef()) {
        if (!getDef()
            .equals(other.getDef())) return false;
      }
      if (hasAffectedRowsCount() != other.hasAffectedRowsCount()) return false;
      if (hasAffectedRowsCount()) {
        if (getAffectedRowsCount()
            != other.getAffectedRowsCount()) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasQueryId()) {
        hash = (37 * hash) + QUERY_ID_FIELD_NUMBER;
        hash = (53 * hash) + getQueryId().hashCode();
      }
      if (hasRowCount()) {
        hash = (37 * hash) + ROW_COUNT_FIELD_NUMBER;
        hash = (53 * hash) + getRowCount();
      }
      if (hasDef()) {
        hash = (37 * hash) + DEF_FIELD_NUMBER;
        hash = (53 * hash) + getDef().hashCode();
      }
      if (hasAffectedRowsCount()) {
        hash = (37 * hash) + AFFECTED_ROWS_COUNT_FIELD_NUMBER;
        hash = (53 * hash) + getAffectedRowsCount();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserBitShared.QueryData parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryData parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryData parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryData 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.drill.exec.proto.UserBitShared.QueryData parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryData parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryData parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryData 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.drill.exec.proto.UserBitShared.QueryData parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryData 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.drill.exec.proto.UserBitShared.QueryData parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryData 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.drill.exec.proto.UserBitShared.QueryData 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>
     * Used by the server when sending query result data batches to the client
     * </pre>
     *
     * Protobuf type {@code exec.shared.QueryData}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.shared.QueryData)
        org.apache.drill.exec.proto.UserBitShared.QueryDataOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_QueryData_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_QueryData_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserBitShared.QueryData.class, org.apache.drill.exec.proto.UserBitShared.QueryData.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserBitShared.QueryData.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getQueryIdFieldBuilder();
          getDefFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        if (queryIdBuilder_ == null) {
          queryId_ = null;
        } else {
          queryIdBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        rowCount_ = 0;
        bitField0_ = (bitField0_ & ~0x00000002);
        if (defBuilder_ == null) {
          def_ = null;
        } else {
          defBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        affectedRowsCount_ = 0;
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_QueryData_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.QueryData getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserBitShared.QueryData.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.QueryData build() {
        org.apache.drill.exec.proto.UserBitShared.QueryData result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.QueryData buildPartial() {
        org.apache.drill.exec.proto.UserBitShared.QueryData result = new org.apache.drill.exec.proto.UserBitShared.QueryData(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          if (queryIdBuilder_ == null) {
            result.queryId_ = queryId_;
          } else {
            result.queryId_ = queryIdBuilder_.build();
          }
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.rowCount_ = rowCount_;
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          if (defBuilder_ == null) {
            result.def_ = def_;
          } else {
            result.def_ = defBuilder_.build();
          }
          to_bitField0_ |= 0x00000004;
        }
        if (((from_bitField0_ & 0x00000008) != 0)) {
          result.affectedRowsCount_ = affectedRowsCount_;
          to_bitField0_ |= 0x00000008;
        }
        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.drill.exec.proto.UserBitShared.QueryData) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.QueryData)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.QueryData other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.QueryData.getDefaultInstance()) return this;
        if (other.hasQueryId()) {
          mergeQueryId(other.getQueryId());
        }
        if (other.hasRowCount()) {
          setRowCount(other.getRowCount());
        }
        if (other.hasDef()) {
          mergeDef(other.getDef());
        }
        if (other.hasAffectedRowsCount()) {
          setAffectedRowsCount(other.getAffectedRowsCount());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        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 {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                input.readMessage(
                    getQueryIdFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 16: {
                rowCount_ = input.readInt32();
                bitField0_ |= 0x00000002;
                break;
              } // case 16
              case 26: {
                input.readMessage(
                    getDefFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000004;
                break;
              } // case 26
              case 32: {
                affectedRowsCount_ = input.readInt32();
                bitField0_ |= 0x00000008;
                break;
              } // case 32
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private org.apache.drill.exec.proto.UserBitShared.QueryId queryId_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.QueryId, org.apache.drill.exec.proto.UserBitShared.QueryId.Builder, org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder> queryIdBuilder_;
      /**
       * <code>optional .exec.shared.QueryId query_id = 1;</code>
       * @return Whether the queryId field is set.
       */
      public boolean hasQueryId() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 1;</code>
       * @return The queryId.
       */
      public org.apache.drill.exec.proto.UserBitShared.QueryId getQueryId() {
        if (queryIdBuilder_ == null) {
          return queryId_ == null ? org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance() : queryId_;
        } else {
          return queryIdBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 1;</code>
       */
      public Builder setQueryId(org.apache.drill.exec.proto.UserBitShared.QueryId value) {
        if (queryIdBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          queryId_ = value;
          onChanged();
        } else {
          queryIdBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 1;</code>
       */
      public Builder setQueryId(
          org.apache.drill.exec.proto.UserBitShared.QueryId.Builder builderForValue) {
        if (queryIdBuilder_ == null) {
          queryId_ = builderForValue.build();
          onChanged();
        } else {
          queryIdBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 1;</code>
       */
      public Builder mergeQueryId(org.apache.drill.exec.proto.UserBitShared.QueryId value) {
        if (queryIdBuilder_ == null) {
          if (((bitField0_ & 0x00000001) != 0) &&
              queryId_ != null &&
              queryId_ != org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance()) {
            queryId_ =
              org.apache.drill.exec.proto.UserBitShared.QueryId.newBuilder(queryId_).mergeFrom(value).buildPartial();
          } else {
            queryId_ = value;
          }
          onChanged();
        } else {
          queryIdBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 1;</code>
       */
      public Builder clearQueryId() {
        if (queryIdBuilder_ == null) {
          queryId_ = null;
          onChanged();
        } else {
          queryIdBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 1;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.QueryId.Builder getQueryIdBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getQueryIdFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 1;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder getQueryIdOrBuilder() {
        if (queryIdBuilder_ != null) {
          return queryIdBuilder_.getMessageOrBuilder();
        } else {
          return queryId_ == null ?
              org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance() : queryId_;
        }
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 1;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.QueryId, org.apache.drill.exec.proto.UserBitShared.QueryId.Builder, org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder> 
          getQueryIdFieldBuilder() {
        if (queryIdBuilder_ == null) {
          queryIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.QueryId, org.apache.drill.exec.proto.UserBitShared.QueryId.Builder, org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder>(
                  getQueryId(),
                  getParentForChildren(),
                  isClean());
          queryId_ = null;
        }
        return queryIdBuilder_;
      }

      private int rowCount_ ;
      /**
       * <code>optional int32 row_count = 2;</code>
       * @return Whether the rowCount field is set.
       */
      @java.lang.Override
      public boolean hasRowCount() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional int32 row_count = 2;</code>
       * @return The rowCount.
       */
      @java.lang.Override
      public int getRowCount() {
        return rowCount_;
      }
      /**
       * <code>optional int32 row_count = 2;</code>
       * @param value The rowCount to set.
       * @return This builder for chaining.
       */
      public Builder setRowCount(int value) {
        bitField0_ |= 0x00000002;
        rowCount_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 row_count = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearRowCount() {
        bitField0_ = (bitField0_ & ~0x00000002);
        rowCount_ = 0;
        onChanged();
        return this;
      }

      private org.apache.drill.exec.proto.UserBitShared.RecordBatchDef def_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.RecordBatchDef, org.apache.drill.exec.proto.UserBitShared.RecordBatchDef.Builder, org.apache.drill.exec.proto.UserBitShared.RecordBatchDefOrBuilder> defBuilder_;
      /**
       * <code>optional .exec.shared.RecordBatchDef def = 3;</code>
       * @return Whether the def field is set.
       */
      public boolean hasDef() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional .exec.shared.RecordBatchDef def = 3;</code>
       * @return The def.
       */
      public org.apache.drill.exec.proto.UserBitShared.RecordBatchDef getDef() {
        if (defBuilder_ == null) {
          return def_ == null ? org.apache.drill.exec.proto.UserBitShared.RecordBatchDef.getDefaultInstance() : def_;
        } else {
          return defBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.shared.RecordBatchDef def = 3;</code>
       */
      public Builder setDef(org.apache.drill.exec.proto.UserBitShared.RecordBatchDef value) {
        if (defBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          def_ = value;
          onChanged();
        } else {
          defBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.shared.RecordBatchDef def = 3;</code>
       */
      public Builder setDef(
          org.apache.drill.exec.proto.UserBitShared.RecordBatchDef.Builder builderForValue) {
        if (defBuilder_ == null) {
          def_ = builderForValue.build();
          onChanged();
        } else {
          defBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.shared.RecordBatchDef def = 3;</code>
       */
      public Builder mergeDef(org.apache.drill.exec.proto.UserBitShared.RecordBatchDef value) {
        if (defBuilder_ == null) {
          if (((bitField0_ & 0x00000004) != 0) &&
              def_ != null &&
              def_ != org.apache.drill.exec.proto.UserBitShared.RecordBatchDef.getDefaultInstance()) {
            def_ =
              org.apache.drill.exec.proto.UserBitShared.RecordBatchDef.newBuilder(def_).mergeFrom(value).buildPartial();
          } else {
            def_ = value;
          }
          onChanged();
        } else {
          defBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.shared.RecordBatchDef def = 3;</code>
       */
      public Builder clearDef() {
        if (defBuilder_ == null) {
          def_ = null;
          onChanged();
        } else {
          defBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }
      /**
       * <code>optional .exec.shared.RecordBatchDef def = 3;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.RecordBatchDef.Builder getDefBuilder() {
        bitField0_ |= 0x00000004;
        onChanged();
        return getDefFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.shared.RecordBatchDef def = 3;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.RecordBatchDefOrBuilder getDefOrBuilder() {
        if (defBuilder_ != null) {
          return defBuilder_.getMessageOrBuilder();
        } else {
          return def_ == null ?
              org.apache.drill.exec.proto.UserBitShared.RecordBatchDef.getDefaultInstance() : def_;
        }
      }
      /**
       * <code>optional .exec.shared.RecordBatchDef def = 3;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.RecordBatchDef, org.apache.drill.exec.proto.UserBitShared.RecordBatchDef.Builder, org.apache.drill.exec.proto.UserBitShared.RecordBatchDefOrBuilder> 
          getDefFieldBuilder() {
        if (defBuilder_ == null) {
          defBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.RecordBatchDef, org.apache.drill.exec.proto.UserBitShared.RecordBatchDef.Builder, org.apache.drill.exec.proto.UserBitShared.RecordBatchDefOrBuilder>(
                  getDef(),
                  getParentForChildren(),
                  isClean());
          def_ = null;
        }
        return defBuilder_;
      }

      private int affectedRowsCount_ ;
      /**
       * <code>optional int32 affected_rows_count = 4;</code>
       * @return Whether the affectedRowsCount field is set.
       */
      @java.lang.Override
      public boolean hasAffectedRowsCount() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <code>optional int32 affected_rows_count = 4;</code>
       * @return The affectedRowsCount.
       */
      @java.lang.Override
      public int getAffectedRowsCount() {
        return affectedRowsCount_;
      }
      /**
       * <code>optional int32 affected_rows_count = 4;</code>
       * @param value The affectedRowsCount to set.
       * @return This builder for chaining.
       */
      public Builder setAffectedRowsCount(int value) {
        bitField0_ |= 0x00000008;
        affectedRowsCount_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 affected_rows_count = 4;</code>
       * @return This builder for chaining.
       */
      public Builder clearAffectedRowsCount() {
        bitField0_ = (bitField0_ & ~0x00000008);
        affectedRowsCount_ = 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:exec.shared.QueryData)
    }

    // @@protoc_insertion_point(class_scope:exec.shared.QueryData)
    private static final org.apache.drill.exec.proto.UserBitShared.QueryData DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserBitShared.QueryData();
    }

    public static org.apache.drill.exec.proto.UserBitShared.QueryData getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<QueryData>
        PARSER = new com.google.protobuf.AbstractParser<QueryData>() {
      @java.lang.Override
      public QueryData parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

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

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

    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.QueryData getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface QueryInfoOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.shared.QueryInfo)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional string query = 1;</code>
     * @return Whether the query field is set.
     */
    boolean hasQuery();
    /**
     * <code>optional string query = 1;</code>
     * @return The query.
     */
    java.lang.String getQuery();
    /**
     * <code>optional string query = 1;</code>
     * @return The bytes for query.
     */
    com.google.protobuf.ByteString
        getQueryBytes();

    /**
     * <code>optional int64 start = 2;</code>
     * @return Whether the start field is set.
     */
    boolean hasStart();
    /**
     * <code>optional int64 start = 2;</code>
     * @return The start.
     */
    long getStart();

    /**
     * <code>optional .exec.shared.QueryResult.QueryState state = 3;</code>
     * @return Whether the state field is set.
     */
    boolean hasState();
    /**
     * <code>optional .exec.shared.QueryResult.QueryState state = 3;</code>
     * @return The state.
     */
    org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState getState();

    /**
     * <code>optional string user = 4 [default = "-"];</code>
     * @return Whether the user field is set.
     */
    boolean hasUser();
    /**
     * <code>optional string user = 4 [default = "-"];</code>
     * @return The user.
     */
    java.lang.String getUser();
    /**
     * <code>optional string user = 4 [default = "-"];</code>
     * @return The bytes for user.
     */
    com.google.protobuf.ByteString
        getUserBytes();

    /**
     * <code>optional .exec.DrillbitEndpoint foreman = 5;</code>
     * @return Whether the foreman field is set.
     */
    boolean hasForeman();
    /**
     * <code>optional .exec.DrillbitEndpoint foreman = 5;</code>
     * @return The foreman.
     */
    org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint getForeman();
    /**
     * <code>optional .exec.DrillbitEndpoint foreman = 5;</code>
     */
    org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder getForemanOrBuilder();

    /**
     * <code>optional string options_json = 6;</code>
     * @return Whether the optionsJson field is set.
     */
    boolean hasOptionsJson();
    /**
     * <code>optional string options_json = 6;</code>
     * @return The optionsJson.
     */
    java.lang.String getOptionsJson();
    /**
     * <code>optional string options_json = 6;</code>
     * @return The bytes for optionsJson.
     */
    com.google.protobuf.ByteString
        getOptionsJsonBytes();

    /**
     * <code>optional double total_cost = 7;</code>
     * @return Whether the totalCost field is set.
     */
    boolean hasTotalCost();
    /**
     * <code>optional double total_cost = 7;</code>
     * @return The totalCost.
     */
    double getTotalCost();

    /**
     * <code>optional string queue_name = 8 [default = "-"];</code>
     * @return Whether the queueName field is set.
     */
    boolean hasQueueName();
    /**
     * <code>optional string queue_name = 8 [default = "-"];</code>
     * @return The queueName.
     */
    java.lang.String getQueueName();
    /**
     * <code>optional string queue_name = 8 [default = "-"];</code>
     * @return The bytes for queueName.
     */
    com.google.protobuf.ByteString
        getQueueNameBytes();
  }
  /**
   * Protobuf type {@code exec.shared.QueryInfo}
   */
  public static final class QueryInfo extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.QueryInfo)
      QueryInfoOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use QueryInfo.newBuilder() to construct.
    private QueryInfo(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private QueryInfo() {
      query_ = "";
      state_ = 0;
      user_ = "-";
      optionsJson_ = "";
      queueName_ = "-";
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new QueryInfo();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_QueryInfo_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_QueryInfo_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserBitShared.QueryInfo.class, org.apache.drill.exec.proto.UserBitShared.QueryInfo.Builder.class);
    }

    private int bitField0_;
    public static final int QUERY_FIELD_NUMBER = 1;
    private volatile java.lang.Object query_;
    /**
     * <code>optional string query = 1;</code>
     * @return Whether the query field is set.
     */
    @java.lang.Override
    public boolean hasQuery() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional string query = 1;</code>
     * @return The query.
     */
    @java.lang.Override
    public java.lang.String getQuery() {
      java.lang.Object ref = query_;
      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();
        if (bs.isValidUtf8()) {
          query_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string query = 1;</code>
     * @return The bytes for query.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getQueryBytes() {
      java.lang.Object ref = query_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        query_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int START_FIELD_NUMBER = 2;
    private long start_;
    /**
     * <code>optional int64 start = 2;</code>
     * @return Whether the start field is set.
     */
    @java.lang.Override
    public boolean hasStart() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional int64 start = 2;</code>
     * @return The start.
     */
    @java.lang.Override
    public long getStart() {
      return start_;
    }

    public static final int STATE_FIELD_NUMBER = 3;
    private int state_;
    /**
     * <code>optional .exec.shared.QueryResult.QueryState state = 3;</code>
     * @return Whether the state field is set.
     */
    @java.lang.Override public boolean hasState() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional .exec.shared.QueryResult.QueryState state = 3;</code>
     * @return The state.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState getState() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState result = org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.valueOf(state_);
      return result == null ? org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.STARTING : result;
    }

    public static final int USER_FIELD_NUMBER = 4;
    private volatile java.lang.Object user_;
    /**
     * <code>optional string user = 4 [default = "-"];</code>
     * @return Whether the user field is set.
     */
    @java.lang.Override
    public boolean hasUser() {
      return ((bitField0_ & 0x00000008) != 0);
    }
    /**
     * <code>optional string user = 4 [default = "-"];</code>
     * @return The user.
     */
    @java.lang.Override
    public java.lang.String getUser() {
      java.lang.Object ref = user_;
      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();
        if (bs.isValidUtf8()) {
          user_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string user = 4 [default = "-"];</code>
     * @return The bytes for user.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getUserBytes() {
      java.lang.Object ref = user_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        user_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int FOREMAN_FIELD_NUMBER = 5;
    private org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint foreman_;
    /**
     * <code>optional .exec.DrillbitEndpoint foreman = 5;</code>
     * @return Whether the foreman field is set.
     */
    @java.lang.Override
    public boolean hasForeman() {
      return ((bitField0_ & 0x00000010) != 0);
    }
    /**
     * <code>optional .exec.DrillbitEndpoint foreman = 5;</code>
     * @return The foreman.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint getForeman() {
      return foreman_ == null ? org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance() : foreman_;
    }
    /**
     * <code>optional .exec.DrillbitEndpoint foreman = 5;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder getForemanOrBuilder() {
      return foreman_ == null ? org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance() : foreman_;
    }

    public static final int OPTIONS_JSON_FIELD_NUMBER = 6;
    private volatile java.lang.Object optionsJson_;
    /**
     * <code>optional string options_json = 6;</code>
     * @return Whether the optionsJson field is set.
     */
    @java.lang.Override
    public boolean hasOptionsJson() {
      return ((bitField0_ & 0x00000020) != 0);
    }
    /**
     * <code>optional string options_json = 6;</code>
     * @return The optionsJson.
     */
    @java.lang.Override
    public java.lang.String getOptionsJson() {
      java.lang.Object ref = optionsJson_;
      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();
        if (bs.isValidUtf8()) {
          optionsJson_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string options_json = 6;</code>
     * @return The bytes for optionsJson.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getOptionsJsonBytes() {
      java.lang.Object ref = optionsJson_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        optionsJson_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int TOTAL_COST_FIELD_NUMBER = 7;
    private double totalCost_;
    /**
     * <code>optional double total_cost = 7;</code>
     * @return Whether the totalCost field is set.
     */
    @java.lang.Override
    public boolean hasTotalCost() {
      return ((bitField0_ & 0x00000040) != 0);
    }
    /**
     * <code>optional double total_cost = 7;</code>
     * @return The totalCost.
     */
    @java.lang.Override
    public double getTotalCost() {
      return totalCost_;
    }

    public static final int QUEUE_NAME_FIELD_NUMBER = 8;
    private volatile java.lang.Object queueName_;
    /**
     * <code>optional string queue_name = 8 [default = "-"];</code>
     * @return Whether the queueName field is set.
     */
    @java.lang.Override
    public boolean hasQueueName() {
      return ((bitField0_ & 0x00000080) != 0);
    }
    /**
     * <code>optional string queue_name = 8 [default = "-"];</code>
     * @return The queueName.
     */
    @java.lang.Override
    public java.lang.String getQueueName() {
      java.lang.Object ref = queueName_;
      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();
        if (bs.isValidUtf8()) {
          queueName_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string queue_name = 8 [default = "-"];</code>
     * @return The bytes for queueName.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getQueueNameBytes() {
      java.lang.Object ref = queueName_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        queueName_ = 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 (((bitField0_ & 0x00000001) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, query_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeInt64(2, start_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeEnum(3, state_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 4, user_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        output.writeMessage(5, getForeman());
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 6, optionsJson_);
      }
      if (((bitField0_ & 0x00000040) != 0)) {
        output.writeDouble(7, totalCost_);
      }
      if (((bitField0_ & 0x00000080) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 8, queueName_);
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, query_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, start_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(3, state_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, user_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(5, getForeman());
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, optionsJson_);
      }
      if (((bitField0_ & 0x00000040) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeDoubleSize(7, totalCost_);
      }
      if (((bitField0_ & 0x00000080) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(8, queueName_);
      }
      size += getUnknownFields().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.drill.exec.proto.UserBitShared.QueryInfo)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserBitShared.QueryInfo other = (org.apache.drill.exec.proto.UserBitShared.QueryInfo) obj;

      if (hasQuery() != other.hasQuery()) return false;
      if (hasQuery()) {
        if (!getQuery()
            .equals(other.getQuery())) return false;
      }
      if (hasStart() != other.hasStart()) return false;
      if (hasStart()) {
        if (getStart()
            != other.getStart()) return false;
      }
      if (hasState() != other.hasState()) return false;
      if (hasState()) {
        if (state_ != other.state_) return false;
      }
      if (hasUser() != other.hasUser()) return false;
      if (hasUser()) {
        if (!getUser()
            .equals(other.getUser())) return false;
      }
      if (hasForeman() != other.hasForeman()) return false;
      if (hasForeman()) {
        if (!getForeman()
            .equals(other.getForeman())) return false;
      }
      if (hasOptionsJson() != other.hasOptionsJson()) return false;
      if (hasOptionsJson()) {
        if (!getOptionsJson()
            .equals(other.getOptionsJson())) return false;
      }
      if (hasTotalCost() != other.hasTotalCost()) return false;
      if (hasTotalCost()) {
        if (java.lang.Double.doubleToLongBits(getTotalCost())
            != java.lang.Double.doubleToLongBits(
                other.getTotalCost())) return false;
      }
      if (hasQueueName() != other.hasQueueName()) return false;
      if (hasQueueName()) {
        if (!getQueueName()
            .equals(other.getQueueName())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasQuery()) {
        hash = (37 * hash) + QUERY_FIELD_NUMBER;
        hash = (53 * hash) + getQuery().hashCode();
      }
      if (hasStart()) {
        hash = (37 * hash) + START_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getStart());
      }
      if (hasState()) {
        hash = (37 * hash) + STATE_FIELD_NUMBER;
        hash = (53 * hash) + state_;
      }
      if (hasUser()) {
        hash = (37 * hash) + USER_FIELD_NUMBER;
        hash = (53 * hash) + getUser().hashCode();
      }
      if (hasForeman()) {
        hash = (37 * hash) + FOREMAN_FIELD_NUMBER;
        hash = (53 * hash) + getForeman().hashCode();
      }
      if (hasOptionsJson()) {
        hash = (37 * hash) + OPTIONS_JSON_FIELD_NUMBER;
        hash = (53 * hash) + getOptionsJson().hashCode();
      }
      if (hasTotalCost()) {
        hash = (37 * hash) + TOTAL_COST_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            java.lang.Double.doubleToLongBits(getTotalCost()));
      }
      if (hasQueueName()) {
        hash = (37 * hash) + QUEUE_NAME_FIELD_NUMBER;
        hash = (53 * hash) + getQueueName().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserBitShared.QueryInfo parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryInfo parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryInfo parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryInfo 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.drill.exec.proto.UserBitShared.QueryInfo parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryInfo parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryInfo parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryInfo 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.drill.exec.proto.UserBitShared.QueryInfo parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryInfo 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.drill.exec.proto.UserBitShared.QueryInfo parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryInfo 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.drill.exec.proto.UserBitShared.QueryInfo 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 exec.shared.QueryInfo}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.shared.QueryInfo)
        org.apache.drill.exec.proto.UserBitShared.QueryInfoOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_QueryInfo_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_QueryInfo_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserBitShared.QueryInfo.class, org.apache.drill.exec.proto.UserBitShared.QueryInfo.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserBitShared.QueryInfo.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getForemanFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        query_ = "";
        bitField0_ = (bitField0_ & ~0x00000001);
        start_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        state_ = 0;
        bitField0_ = (bitField0_ & ~0x00000004);
        user_ = "-";
        bitField0_ = (bitField0_ & ~0x00000008);
        if (foremanBuilder_ == null) {
          foreman_ = null;
        } else {
          foremanBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000010);
        optionsJson_ = "";
        bitField0_ = (bitField0_ & ~0x00000020);
        totalCost_ = 0D;
        bitField0_ = (bitField0_ & ~0x00000040);
        queueName_ = "-";
        bitField0_ = (bitField0_ & ~0x00000080);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_QueryInfo_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.QueryInfo getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserBitShared.QueryInfo.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.QueryInfo build() {
        org.apache.drill.exec.proto.UserBitShared.QueryInfo result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.QueryInfo buildPartial() {
        org.apache.drill.exec.proto.UserBitShared.QueryInfo result = new org.apache.drill.exec.proto.UserBitShared.QueryInfo(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.query_ = query_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.start_ = start_;
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          to_bitField0_ |= 0x00000004;
        }
        result.state_ = state_;
        if (((from_bitField0_ & 0x00000008) != 0)) {
          to_bitField0_ |= 0x00000008;
        }
        result.user_ = user_;
        if (((from_bitField0_ & 0x00000010) != 0)) {
          if (foremanBuilder_ == null) {
            result.foreman_ = foreman_;
          } else {
            result.foreman_ = foremanBuilder_.build();
          }
          to_bitField0_ |= 0x00000010;
        }
        if (((from_bitField0_ & 0x00000020) != 0)) {
          to_bitField0_ |= 0x00000020;
        }
        result.optionsJson_ = optionsJson_;
        if (((from_bitField0_ & 0x00000040) != 0)) {
          result.totalCost_ = totalCost_;
          to_bitField0_ |= 0x00000040;
        }
        if (((from_bitField0_ & 0x00000080) != 0)) {
          to_bitField0_ |= 0x00000080;
        }
        result.queueName_ = queueName_;
        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.drill.exec.proto.UserBitShared.QueryInfo) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.QueryInfo)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.QueryInfo other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.QueryInfo.getDefaultInstance()) return this;
        if (other.hasQuery()) {
          bitField0_ |= 0x00000001;
          query_ = other.query_;
          onChanged();
        }
        if (other.hasStart()) {
          setStart(other.getStart());
        }
        if (other.hasState()) {
          setState(other.getState());
        }
        if (other.hasUser()) {
          bitField0_ |= 0x00000008;
          user_ = other.user_;
          onChanged();
        }
        if (other.hasForeman()) {
          mergeForeman(other.getForeman());
        }
        if (other.hasOptionsJson()) {
          bitField0_ |= 0x00000020;
          optionsJson_ = other.optionsJson_;
          onChanged();
        }
        if (other.hasTotalCost()) {
          setTotalCost(other.getTotalCost());
        }
        if (other.hasQueueName()) {
          bitField0_ |= 0x00000080;
          queueName_ = other.queueName_;
          onChanged();
        }
        this.mergeUnknownFields(other.getUnknownFields());
        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 {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                query_ = input.readBytes();
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 16: {
                start_ = input.readInt64();
                bitField0_ |= 0x00000002;
                break;
              } // case 16
              case 24: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState tmpValue =
                    org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(3, tmpRaw);
                } else {
                  state_ = tmpRaw;
                  bitField0_ |= 0x00000004;
                }
                break;
              } // case 24
              case 34: {
                user_ = input.readBytes();
                bitField0_ |= 0x00000008;
                break;
              } // case 34
              case 42: {
                input.readMessage(
                    getForemanFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000010;
                break;
              } // case 42
              case 50: {
                optionsJson_ = input.readBytes();
                bitField0_ |= 0x00000020;
                break;
              } // case 50
              case 57: {
                totalCost_ = input.readDouble();
                bitField0_ |= 0x00000040;
                break;
              } // case 57
              case 66: {
                queueName_ = input.readBytes();
                bitField0_ |= 0x00000080;
                break;
              } // case 66
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.lang.Object query_ = "";
      /**
       * <code>optional string query = 1;</code>
       * @return Whether the query field is set.
       */
      public boolean hasQuery() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional string query = 1;</code>
       * @return The query.
       */
      public java.lang.String getQuery() {
        java.lang.Object ref = query_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            query_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string query = 1;</code>
       * @return The bytes for query.
       */
      public com.google.protobuf.ByteString
          getQueryBytes() {
        java.lang.Object ref = query_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          query_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string query = 1;</code>
       * @param value The query to set.
       * @return This builder for chaining.
       */
      public Builder setQuery(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        query_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string query = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearQuery() {
        bitField0_ = (bitField0_ & ~0x00000001);
        query_ = getDefaultInstance().getQuery();
        onChanged();
        return this;
      }
      /**
       * <code>optional string query = 1;</code>
       * @param value The bytes for query to set.
       * @return This builder for chaining.
       */
      public Builder setQueryBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        query_ = value;
        onChanged();
        return this;
      }

      private long start_ ;
      /**
       * <code>optional int64 start = 2;</code>
       * @return Whether the start field is set.
       */
      @java.lang.Override
      public boolean hasStart() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional int64 start = 2;</code>
       * @return The start.
       */
      @java.lang.Override
      public long getStart() {
        return start_;
      }
      /**
       * <code>optional int64 start = 2;</code>
       * @param value The start to set.
       * @return This builder for chaining.
       */
      public Builder setStart(long value) {
        bitField0_ |= 0x00000002;
        start_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 start = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearStart() {
        bitField0_ = (bitField0_ & ~0x00000002);
        start_ = 0L;
        onChanged();
        return this;
      }

      private int state_ = 0;
      /**
       * <code>optional .exec.shared.QueryResult.QueryState state = 3;</code>
       * @return Whether the state field is set.
       */
      @java.lang.Override public boolean hasState() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional .exec.shared.QueryResult.QueryState state = 3;</code>
       * @return The state.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState getState() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState result = org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.valueOf(state_);
        return result == null ? org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.STARTING : result;
      }
      /**
       * <code>optional .exec.shared.QueryResult.QueryState state = 3;</code>
       * @param value The state to set.
       * @return This builder for chaining.
       */
      public Builder setState(org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000004;
        state_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryResult.QueryState state = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearState() {
        bitField0_ = (bitField0_ & ~0x00000004);
        state_ = 0;
        onChanged();
        return this;
      }

      private java.lang.Object user_ = "-";
      /**
       * <code>optional string user = 4 [default = "-"];</code>
       * @return Whether the user field is set.
       */
      public boolean hasUser() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <code>optional string user = 4 [default = "-"];</code>
       * @return The user.
       */
      public java.lang.String getUser() {
        java.lang.Object ref = user_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            user_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string user = 4 [default = "-"];</code>
       * @return The bytes for user.
       */
      public com.google.protobuf.ByteString
          getUserBytes() {
        java.lang.Object ref = user_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          user_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string user = 4 [default = "-"];</code>
       * @param value The user to set.
       * @return This builder for chaining.
       */
      public Builder setUser(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        user_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string user = 4 [default = "-"];</code>
       * @return This builder for chaining.
       */
      public Builder clearUser() {
        bitField0_ = (bitField0_ & ~0x00000008);
        user_ = getDefaultInstance().getUser();
        onChanged();
        return this;
      }
      /**
       * <code>optional string user = 4 [default = "-"];</code>
       * @param value The bytes for user to set.
       * @return This builder for chaining.
       */
      public Builder setUserBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        user_ = value;
        onChanged();
        return this;
      }

      private org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint foreman_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint, org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder, org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder> foremanBuilder_;
      /**
       * <code>optional .exec.DrillbitEndpoint foreman = 5;</code>
       * @return Whether the foreman field is set.
       */
      public boolean hasForeman() {
        return ((bitField0_ & 0x00000010) != 0);
      }
      /**
       * <code>optional .exec.DrillbitEndpoint foreman = 5;</code>
       * @return The foreman.
       */
      public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint getForeman() {
        if (foremanBuilder_ == null) {
          return foreman_ == null ? org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance() : foreman_;
        } else {
          return foremanBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.DrillbitEndpoint foreman = 5;</code>
       */
      public Builder setForeman(org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint value) {
        if (foremanBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          foreman_ = value;
          onChanged();
        } else {
          foremanBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint foreman = 5;</code>
       */
      public Builder setForeman(
          org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder builderForValue) {
        if (foremanBuilder_ == null) {
          foreman_ = builderForValue.build();
          onChanged();
        } else {
          foremanBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint foreman = 5;</code>
       */
      public Builder mergeForeman(org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint value) {
        if (foremanBuilder_ == null) {
          if (((bitField0_ & 0x00000010) != 0) &&
              foreman_ != null &&
              foreman_ != org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance()) {
            foreman_ =
              org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.newBuilder(foreman_).mergeFrom(value).buildPartial();
          } else {
            foreman_ = value;
          }
          onChanged();
        } else {
          foremanBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint foreman = 5;</code>
       */
      public Builder clearForeman() {
        if (foremanBuilder_ == null) {
          foreman_ = null;
          onChanged();
        } else {
          foremanBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000010);
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint foreman = 5;</code>
       */
      public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder getForemanBuilder() {
        bitField0_ |= 0x00000010;
        onChanged();
        return getForemanFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.DrillbitEndpoint foreman = 5;</code>
       */
      public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder getForemanOrBuilder() {
        if (foremanBuilder_ != null) {
          return foremanBuilder_.getMessageOrBuilder();
        } else {
          return foreman_ == null ?
              org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance() : foreman_;
        }
      }
      /**
       * <code>optional .exec.DrillbitEndpoint foreman = 5;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint, org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder, org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder> 
          getForemanFieldBuilder() {
        if (foremanBuilder_ == null) {
          foremanBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint, org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder, org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder>(
                  getForeman(),
                  getParentForChildren(),
                  isClean());
          foreman_ = null;
        }
        return foremanBuilder_;
      }

      private java.lang.Object optionsJson_ = "";
      /**
       * <code>optional string options_json = 6;</code>
       * @return Whether the optionsJson field is set.
       */
      public boolean hasOptionsJson() {
        return ((bitField0_ & 0x00000020) != 0);
      }
      /**
       * <code>optional string options_json = 6;</code>
       * @return The optionsJson.
       */
      public java.lang.String getOptionsJson() {
        java.lang.Object ref = optionsJson_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            optionsJson_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string options_json = 6;</code>
       * @return The bytes for optionsJson.
       */
      public com.google.protobuf.ByteString
          getOptionsJsonBytes() {
        java.lang.Object ref = optionsJson_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          optionsJson_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string options_json = 6;</code>
       * @param value The optionsJson to set.
       * @return This builder for chaining.
       */
      public Builder setOptionsJson(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000020;
        optionsJson_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string options_json = 6;</code>
       * @return This builder for chaining.
       */
      public Builder clearOptionsJson() {
        bitField0_ = (bitField0_ & ~0x00000020);
        optionsJson_ = getDefaultInstance().getOptionsJson();
        onChanged();
        return this;
      }
      /**
       * <code>optional string options_json = 6;</code>
       * @param value The bytes for optionsJson to set.
       * @return This builder for chaining.
       */
      public Builder setOptionsJsonBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000020;
        optionsJson_ = value;
        onChanged();
        return this;
      }

      private double totalCost_ ;
      /**
       * <code>optional double total_cost = 7;</code>
       * @return Whether the totalCost field is set.
       */
      @java.lang.Override
      public boolean hasTotalCost() {
        return ((bitField0_ & 0x00000040) != 0);
      }
      /**
       * <code>optional double total_cost = 7;</code>
       * @return The totalCost.
       */
      @java.lang.Override
      public double getTotalCost() {
        return totalCost_;
      }
      /**
       * <code>optional double total_cost = 7;</code>
       * @param value The totalCost to set.
       * @return This builder for chaining.
       */
      public Builder setTotalCost(double value) {
        bitField0_ |= 0x00000040;
        totalCost_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional double total_cost = 7;</code>
       * @return This builder for chaining.
       */
      public Builder clearTotalCost() {
        bitField0_ = (bitField0_ & ~0x00000040);
        totalCost_ = 0D;
        onChanged();
        return this;
      }

      private java.lang.Object queueName_ = "-";
      /**
       * <code>optional string queue_name = 8 [default = "-"];</code>
       * @return Whether the queueName field is set.
       */
      public boolean hasQueueName() {
        return ((bitField0_ & 0x00000080) != 0);
      }
      /**
       * <code>optional string queue_name = 8 [default = "-"];</code>
       * @return The queueName.
       */
      public java.lang.String getQueueName() {
        java.lang.Object ref = queueName_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            queueName_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string queue_name = 8 [default = "-"];</code>
       * @return The bytes for queueName.
       */
      public com.google.protobuf.ByteString
          getQueueNameBytes() {
        java.lang.Object ref = queueName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          queueName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string queue_name = 8 [default = "-"];</code>
       * @param value The queueName to set.
       * @return This builder for chaining.
       */
      public Builder setQueueName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000080;
        queueName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string queue_name = 8 [default = "-"];</code>
       * @return This builder for chaining.
       */
      public Builder clearQueueName() {
        bitField0_ = (bitField0_ & ~0x00000080);
        queueName_ = getDefaultInstance().getQueueName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string queue_name = 8 [default = "-"];</code>
       * @param value The bytes for queueName to set.
       * @return This builder for chaining.
       */
      public Builder setQueueNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000080;
        queueName_ = 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:exec.shared.QueryInfo)
    }

    // @@protoc_insertion_point(class_scope:exec.shared.QueryInfo)
    private static final org.apache.drill.exec.proto.UserBitShared.QueryInfo DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserBitShared.QueryInfo();
    }

    public static org.apache.drill.exec.proto.UserBitShared.QueryInfo getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<QueryInfo>
        PARSER = new com.google.protobuf.AbstractParser<QueryInfo>() {
      @java.lang.Override
      public QueryInfo parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

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

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

    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.QueryInfo getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface QueryProfileOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.shared.QueryProfile)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional .exec.shared.QueryId id = 1;</code>
     * @return Whether the id field is set.
     */
    boolean hasId();
    /**
     * <code>optional .exec.shared.QueryId id = 1;</code>
     * @return The id.
     */
    org.apache.drill.exec.proto.UserBitShared.QueryId getId();
    /**
     * <code>optional .exec.shared.QueryId id = 1;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder getIdOrBuilder();

    /**
     * <code>optional .exec.shared.QueryType type = 2;</code>
     * @return Whether the type field is set.
     */
    boolean hasType();
    /**
     * <code>optional .exec.shared.QueryType type = 2;</code>
     * @return The type.
     */
    org.apache.drill.exec.proto.UserBitShared.QueryType getType();

    /**
     * <code>optional int64 start = 3;</code>
     * @return Whether the start field is set.
     */
    boolean hasStart();
    /**
     * <code>optional int64 start = 3;</code>
     * @return The start.
     */
    long getStart();

    /**
     * <code>optional int64 end = 4;</code>
     * @return Whether the end field is set.
     */
    boolean hasEnd();
    /**
     * <code>optional int64 end = 4;</code>
     * @return The end.
     */
    long getEnd();

    /**
     * <code>optional string query = 5;</code>
     * @return Whether the query field is set.
     */
    boolean hasQuery();
    /**
     * <code>optional string query = 5;</code>
     * @return The query.
     */
    java.lang.String getQuery();
    /**
     * <code>optional string query = 5;</code>
     * @return The bytes for query.
     */
    com.google.protobuf.ByteString
        getQueryBytes();

    /**
     * <code>optional string plan = 6;</code>
     * @return Whether the plan field is set.
     */
    boolean hasPlan();
    /**
     * <code>optional string plan = 6;</code>
     * @return The plan.
     */
    java.lang.String getPlan();
    /**
     * <code>optional string plan = 6;</code>
     * @return The bytes for plan.
     */
    com.google.protobuf.ByteString
        getPlanBytes();

    /**
     * <code>optional .exec.DrillbitEndpoint foreman = 7;</code>
     * @return Whether the foreman field is set.
     */
    boolean hasForeman();
    /**
     * <code>optional .exec.DrillbitEndpoint foreman = 7;</code>
     * @return The foreman.
     */
    org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint getForeman();
    /**
     * <code>optional .exec.DrillbitEndpoint foreman = 7;</code>
     */
    org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder getForemanOrBuilder();

    /**
     * <code>optional .exec.shared.QueryResult.QueryState state = 8;</code>
     * @return Whether the state field is set.
     */
    boolean hasState();
    /**
     * <code>optional .exec.shared.QueryResult.QueryState state = 8;</code>
     * @return The state.
     */
    org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState getState();

    /**
     * <code>optional int32 total_fragments = 9;</code>
     * @return Whether the totalFragments field is set.
     */
    boolean hasTotalFragments();
    /**
     * <code>optional int32 total_fragments = 9;</code>
     * @return The totalFragments.
     */
    int getTotalFragments();

    /**
     * <code>optional int32 finished_fragments = 10;</code>
     * @return Whether the finishedFragments field is set.
     */
    boolean hasFinishedFragments();
    /**
     * <code>optional int32 finished_fragments = 10;</code>
     * @return The finishedFragments.
     */
    int getFinishedFragments();

    /**
     * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
     */
    java.util.List<org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile> 
        getFragmentProfileList();
    /**
     * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile getFragmentProfile(int index);
    /**
     * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
     */
    int getFragmentProfileCount();
    /**
     * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
     */
    java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfileOrBuilder> 
        getFragmentProfileOrBuilderList();
    /**
     * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfileOrBuilder getFragmentProfileOrBuilder(
        int index);

    /**
     * <code>optional string user = 12 [default = "-"];</code>
     * @return Whether the user field is set.
     */
    boolean hasUser();
    /**
     * <code>optional string user = 12 [default = "-"];</code>
     * @return The user.
     */
    java.lang.String getUser();
    /**
     * <code>optional string user = 12 [default = "-"];</code>
     * @return The bytes for user.
     */
    com.google.protobuf.ByteString
        getUserBytes();

    /**
     * <code>optional string error = 13;</code>
     * @return Whether the error field is set.
     */
    boolean hasError();
    /**
     * <code>optional string error = 13;</code>
     * @return The error.
     */
    java.lang.String getError();
    /**
     * <code>optional string error = 13;</code>
     * @return The bytes for error.
     */
    com.google.protobuf.ByteString
        getErrorBytes();

    /**
     * <code>optional string verboseError = 14;</code>
     * @return Whether the verboseError field is set.
     */
    boolean hasVerboseError();
    /**
     * <code>optional string verboseError = 14;</code>
     * @return The verboseError.
     */
    java.lang.String getVerboseError();
    /**
     * <code>optional string verboseError = 14;</code>
     * @return The bytes for verboseError.
     */
    com.google.protobuf.ByteString
        getVerboseErrorBytes();

    /**
     * <code>optional string error_id = 15;</code>
     * @return Whether the errorId field is set.
     */
    boolean hasErrorId();
    /**
     * <code>optional string error_id = 15;</code>
     * @return The errorId.
     */
    java.lang.String getErrorId();
    /**
     * <code>optional string error_id = 15;</code>
     * @return The bytes for errorId.
     */
    com.google.protobuf.ByteString
        getErrorIdBytes();

    /**
     * <code>optional string error_node = 16;</code>
     * @return Whether the errorNode field is set.
     */
    boolean hasErrorNode();
    /**
     * <code>optional string error_node = 16;</code>
     * @return The errorNode.
     */
    java.lang.String getErrorNode();
    /**
     * <code>optional string error_node = 16;</code>
     * @return The bytes for errorNode.
     */
    com.google.protobuf.ByteString
        getErrorNodeBytes();

    /**
     * <code>optional string options_json = 17;</code>
     * @return Whether the optionsJson field is set.
     */
    boolean hasOptionsJson();
    /**
     * <code>optional string options_json = 17;</code>
     * @return The optionsJson.
     */
    java.lang.String getOptionsJson();
    /**
     * <code>optional string options_json = 17;</code>
     * @return The bytes for optionsJson.
     */
    com.google.protobuf.ByteString
        getOptionsJsonBytes();

    /**
     * <code>optional int64 planEnd = 18;</code>
     * @return Whether the planEnd field is set.
     */
    boolean hasPlanEnd();
    /**
     * <code>optional int64 planEnd = 18;</code>
     * @return The planEnd.
     */
    long getPlanEnd();

    /**
     * <code>optional int64 queueWaitEnd = 19;</code>
     * @return Whether the queueWaitEnd field is set.
     */
    boolean hasQueueWaitEnd();
    /**
     * <code>optional int64 queueWaitEnd = 19;</code>
     * @return The queueWaitEnd.
     */
    long getQueueWaitEnd();

    /**
     * <code>optional double total_cost = 20;</code>
     * @return Whether the totalCost field is set.
     */
    boolean hasTotalCost();
    /**
     * <code>optional double total_cost = 20;</code>
     * @return The totalCost.
     */
    double getTotalCost();

    /**
     * <code>optional string queue_name = 21 [default = "-"];</code>
     * @return Whether the queueName field is set.
     */
    boolean hasQueueName();
    /**
     * <code>optional string queue_name = 21 [default = "-"];</code>
     * @return The queueName.
     */
    java.lang.String getQueueName();
    /**
     * <code>optional string queue_name = 21 [default = "-"];</code>
     * @return The bytes for queueName.
     */
    com.google.protobuf.ByteString
        getQueueNameBytes();

    /**
     * <code>optional string queryId = 22;</code>
     * @return Whether the queryId field is set.
     */
    boolean hasQueryId();
    /**
     * <code>optional string queryId = 22;</code>
     * @return The queryId.
     */
    java.lang.String getQueryId();
    /**
     * <code>optional string queryId = 22;</code>
     * @return The bytes for queryId.
     */
    com.google.protobuf.ByteString
        getQueryIdBytes();

    /**
     * <code>optional int32 autoLimit = 23;</code>
     * @return Whether the autoLimit field is set.
     */
    boolean hasAutoLimit();
    /**
     * <code>optional int32 autoLimit = 23;</code>
     * @return The autoLimit.
     */
    int getAutoLimit();

    /**
     * <code>repeated string scanned_plugins = 24;</code>
     * @return A list containing the scannedPlugins.
     */
    java.util.List<java.lang.String>
        getScannedPluginsList();
    /**
     * <code>repeated string scanned_plugins = 24;</code>
     * @return The count of scannedPlugins.
     */
    int getScannedPluginsCount();
    /**
     * <code>repeated string scanned_plugins = 24;</code>
     * @param index The index of the element to return.
     * @return The scannedPlugins at the given index.
     */
    java.lang.String getScannedPlugins(int index);
    /**
     * <code>repeated string scanned_plugins = 24;</code>
     * @param index The index of the value to return.
     * @return The bytes of the scannedPlugins at the given index.
     */
    com.google.protobuf.ByteString
        getScannedPluginsBytes(int index);
  }
  /**
   * Protobuf type {@code exec.shared.QueryProfile}
   */
  public static final class QueryProfile extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.QueryProfile)
      QueryProfileOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use QueryProfile.newBuilder() to construct.
    private QueryProfile(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private QueryProfile() {
      type_ = 1;
      query_ = "";
      plan_ = "";
      state_ = 0;
      fragmentProfile_ = java.util.Collections.emptyList();
      user_ = "-";
      error_ = "";
      verboseError_ = "";
      errorId_ = "";
      errorNode_ = "";
      optionsJson_ = "";
      queueName_ = "-";
      queryId_ = "";
      scannedPlugins_ = com.google.protobuf.LazyStringArrayList.EMPTY;
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new QueryProfile();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_QueryProfile_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_QueryProfile_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserBitShared.QueryProfile.class, org.apache.drill.exec.proto.UserBitShared.QueryProfile.Builder.class);
    }

    private int bitField0_;
    public static final int ID_FIELD_NUMBER = 1;
    private org.apache.drill.exec.proto.UserBitShared.QueryId id_;
    /**
     * <code>optional .exec.shared.QueryId id = 1;</code>
     * @return Whether the id field is set.
     */
    @java.lang.Override
    public boolean hasId() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional .exec.shared.QueryId id = 1;</code>
     * @return The id.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.QueryId getId() {
      return id_ == null ? org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance() : id_;
    }
    /**
     * <code>optional .exec.shared.QueryId id = 1;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder getIdOrBuilder() {
      return id_ == null ? org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance() : id_;
    }

    public static final int TYPE_FIELD_NUMBER = 2;
    private int type_;
    /**
     * <code>optional .exec.shared.QueryType type = 2;</code>
     * @return Whether the type field is set.
     */
    @java.lang.Override public boolean hasType() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .exec.shared.QueryType type = 2;</code>
     * @return The type.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserBitShared.QueryType getType() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserBitShared.QueryType result = org.apache.drill.exec.proto.UserBitShared.QueryType.valueOf(type_);
      return result == null ? org.apache.drill.exec.proto.UserBitShared.QueryType.SQL : result;
    }

    public static final int START_FIELD_NUMBER = 3;
    private long start_;
    /**
     * <code>optional int64 start = 3;</code>
     * @return Whether the start field is set.
     */
    @java.lang.Override
    public boolean hasStart() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional int64 start = 3;</code>
     * @return The start.
     */
    @java.lang.Override
    public long getStart() {
      return start_;
    }

    public static final int END_FIELD_NUMBER = 4;
    private long end_;
    /**
     * <code>optional int64 end = 4;</code>
     * @return Whether the end field is set.
     */
    @java.lang.Override
    public boolean hasEnd() {
      return ((bitField0_ & 0x00000008) != 0);
    }
    /**
     * <code>optional int64 end = 4;</code>
     * @return The end.
     */
    @java.lang.Override
    public long getEnd() {
      return end_;
    }

    public static final int QUERY_FIELD_NUMBER = 5;
    private volatile java.lang.Object query_;
    /**
     * <code>optional string query = 5;</code>
     * @return Whether the query field is set.
     */
    @java.lang.Override
    public boolean hasQuery() {
      return ((bitField0_ & 0x00000010) != 0);
    }
    /**
     * <code>optional string query = 5;</code>
     * @return The query.
     */
    @java.lang.Override
    public java.lang.String getQuery() {
      java.lang.Object ref = query_;
      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();
        if (bs.isValidUtf8()) {
          query_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string query = 5;</code>
     * @return The bytes for query.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getQueryBytes() {
      java.lang.Object ref = query_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        query_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int PLAN_FIELD_NUMBER = 6;
    private volatile java.lang.Object plan_;
    /**
     * <code>optional string plan = 6;</code>
     * @return Whether the plan field is set.
     */
    @java.lang.Override
    public boolean hasPlan() {
      return ((bitField0_ & 0x00000020) != 0);
    }
    /**
     * <code>optional string plan = 6;</code>
     * @return The plan.
     */
    @java.lang.Override
    public java.lang.String getPlan() {
      java.lang.Object ref = plan_;
      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();
        if (bs.isValidUtf8()) {
          plan_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string plan = 6;</code>
     * @return The bytes for plan.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getPlanBytes() {
      java.lang.Object ref = plan_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        plan_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int FOREMAN_FIELD_NUMBER = 7;
    private org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint foreman_;
    /**
     * <code>optional .exec.DrillbitEndpoint foreman = 7;</code>
     * @return Whether the foreman field is set.
     */
    @java.lang.Override
    public boolean hasForeman() {
      return ((bitField0_ & 0x00000040) != 0);
    }
    /**
     * <code>optional .exec.DrillbitEndpoint foreman = 7;</code>
     * @return The foreman.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint getForeman() {
      return foreman_ == null ? org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance() : foreman_;
    }
    /**
     * <code>optional .exec.DrillbitEndpoint foreman = 7;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder getForemanOrBuilder() {
      return foreman_ == null ? org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance() : foreman_;
    }

    public static final int STATE_FIELD_NUMBER = 8;
    private int state_;
    /**
     * <code>optional .exec.shared.QueryResult.QueryState state = 8;</code>
     * @return Whether the state field is set.
     */
    @java.lang.Override public boolean hasState() {
      return ((bitField0_ & 0x00000080) != 0);
    }
    /**
     * <code>optional .exec.shared.QueryResult.QueryState state = 8;</code>
     * @return The state.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState getState() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState result = org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.valueOf(state_);
      return result == null ? org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.STARTING : result;
    }

    public static final int TOTAL_FRAGMENTS_FIELD_NUMBER = 9;
    private int totalFragments_;
    /**
     * <code>optional int32 total_fragments = 9;</code>
     * @return Whether the totalFragments field is set.
     */
    @java.lang.Override
    public boolean hasTotalFragments() {
      return ((bitField0_ & 0x00000100) != 0);
    }
    /**
     * <code>optional int32 total_fragments = 9;</code>
     * @return The totalFragments.
     */
    @java.lang.Override
    public int getTotalFragments() {
      return totalFragments_;
    }

    public static final int FINISHED_FRAGMENTS_FIELD_NUMBER = 10;
    private int finishedFragments_;
    /**
     * <code>optional int32 finished_fragments = 10;</code>
     * @return Whether the finishedFragments field is set.
     */
    @java.lang.Override
    public boolean hasFinishedFragments() {
      return ((bitField0_ & 0x00000200) != 0);
    }
    /**
     * <code>optional int32 finished_fragments = 10;</code>
     * @return The finishedFragments.
     */
    @java.lang.Override
    public int getFinishedFragments() {
      return finishedFragments_;
    }

    public static final int FRAGMENT_PROFILE_FIELD_NUMBER = 11;
    private java.util.List<org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile> fragmentProfile_;
    /**
     * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile> getFragmentProfileList() {
      return fragmentProfile_;
    }
    /**
     * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
     */
    @java.lang.Override
    public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfileOrBuilder> 
        getFragmentProfileOrBuilderList() {
      return fragmentProfile_;
    }
    /**
     * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
     */
    @java.lang.Override
    public int getFragmentProfileCount() {
      return fragmentProfile_.size();
    }
    /**
     * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile getFragmentProfile(int index) {
      return fragmentProfile_.get(index);
    }
    /**
     * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfileOrBuilder getFragmentProfileOrBuilder(
        int index) {
      return fragmentProfile_.get(index);
    }

    public static final int USER_FIELD_NUMBER = 12;
    private volatile java.lang.Object user_;
    /**
     * <code>optional string user = 12 [default = "-"];</code>
     * @return Whether the user field is set.
     */
    @java.lang.Override
    public boolean hasUser() {
      return ((bitField0_ & 0x00000400) != 0);
    }
    /**
     * <code>optional string user = 12 [default = "-"];</code>
     * @return The user.
     */
    @java.lang.Override
    public java.lang.String getUser() {
      java.lang.Object ref = user_;
      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();
        if (bs.isValidUtf8()) {
          user_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string user = 12 [default = "-"];</code>
     * @return The bytes for user.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getUserBytes() {
      java.lang.Object ref = user_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        user_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int ERROR_FIELD_NUMBER = 13;
    private volatile java.lang.Object error_;
    /**
     * <code>optional string error = 13;</code>
     * @return Whether the error field is set.
     */
    @java.lang.Override
    public boolean hasError() {
      return ((bitField0_ & 0x00000800) != 0);
    }
    /**
     * <code>optional string error = 13;</code>
     * @return The error.
     */
    @java.lang.Override
    public java.lang.String getError() {
      java.lang.Object ref = error_;
      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();
        if (bs.isValidUtf8()) {
          error_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string error = 13;</code>
     * @return The bytes for error.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getErrorBytes() {
      java.lang.Object ref = error_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        error_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int VERBOSEERROR_FIELD_NUMBER = 14;
    private volatile java.lang.Object verboseError_;
    /**
     * <code>optional string verboseError = 14;</code>
     * @return Whether the verboseError field is set.
     */
    @java.lang.Override
    public boolean hasVerboseError() {
      return ((bitField0_ & 0x00001000) != 0);
    }
    /**
     * <code>optional string verboseError = 14;</code>
     * @return The verboseError.
     */
    @java.lang.Override
    public java.lang.String getVerboseError() {
      java.lang.Object ref = verboseError_;
      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();
        if (bs.isValidUtf8()) {
          verboseError_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string verboseError = 14;</code>
     * @return The bytes for verboseError.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getVerboseErrorBytes() {
      java.lang.Object ref = verboseError_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        verboseError_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int ERROR_ID_FIELD_NUMBER = 15;
    private volatile java.lang.Object errorId_;
    /**
     * <code>optional string error_id = 15;</code>
     * @return Whether the errorId field is set.
     */
    @java.lang.Override
    public boolean hasErrorId() {
      return ((bitField0_ & 0x00002000) != 0);
    }
    /**
     * <code>optional string error_id = 15;</code>
     * @return The errorId.
     */
    @java.lang.Override
    public java.lang.String getErrorId() {
      java.lang.Object ref = errorId_;
      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();
        if (bs.isValidUtf8()) {
          errorId_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string error_id = 15;</code>
     * @return The bytes for errorId.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getErrorIdBytes() {
      java.lang.Object ref = errorId_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        errorId_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int ERROR_NODE_FIELD_NUMBER = 16;
    private volatile java.lang.Object errorNode_;
    /**
     * <code>optional string error_node = 16;</code>
     * @return Whether the errorNode field is set.
     */
    @java.lang.Override
    public boolean hasErrorNode() {
      return ((bitField0_ & 0x00004000) != 0);
    }
    /**
     * <code>optional string error_node = 16;</code>
     * @return The errorNode.
     */
    @java.lang.Override
    public java.lang.String getErrorNode() {
      java.lang.Object ref = errorNode_;
      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();
        if (bs.isValidUtf8()) {
          errorNode_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string error_node = 16;</code>
     * @return The bytes for errorNode.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getErrorNodeBytes() {
      java.lang.Object ref = errorNode_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        errorNode_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int OPTIONS_JSON_FIELD_NUMBER = 17;
    private volatile java.lang.Object optionsJson_;
    /**
     * <code>optional string options_json = 17;</code>
     * @return Whether the optionsJson field is set.
     */
    @java.lang.Override
    public boolean hasOptionsJson() {
      return ((bitField0_ & 0x00008000) != 0);
    }
    /**
     * <code>optional string options_json = 17;</code>
     * @return The optionsJson.
     */
    @java.lang.Override
    public java.lang.String getOptionsJson() {
      java.lang.Object ref = optionsJson_;
      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();
        if (bs.isValidUtf8()) {
          optionsJson_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string options_json = 17;</code>
     * @return The bytes for optionsJson.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getOptionsJsonBytes() {
      java.lang.Object ref = optionsJson_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        optionsJson_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int PLANEND_FIELD_NUMBER = 18;
    private long planEnd_;
    /**
     * <code>optional int64 planEnd = 18;</code>
     * @return Whether the planEnd field is set.
     */
    @java.lang.Override
    public boolean hasPlanEnd() {
      return ((bitField0_ & 0x00010000) != 0);
    }
    /**
     * <code>optional int64 planEnd = 18;</code>
     * @return The planEnd.
     */
    @java.lang.Override
    public long getPlanEnd() {
      return planEnd_;
    }

    public static final int QUEUEWAITEND_FIELD_NUMBER = 19;
    private long queueWaitEnd_;
    /**
     * <code>optional int64 queueWaitEnd = 19;</code>
     * @return Whether the queueWaitEnd field is set.
     */
    @java.lang.Override
    public boolean hasQueueWaitEnd() {
      return ((bitField0_ & 0x00020000) != 0);
    }
    /**
     * <code>optional int64 queueWaitEnd = 19;</code>
     * @return The queueWaitEnd.
     */
    @java.lang.Override
    public long getQueueWaitEnd() {
      return queueWaitEnd_;
    }

    public static final int TOTAL_COST_FIELD_NUMBER = 20;
    private double totalCost_;
    /**
     * <code>optional double total_cost = 20;</code>
     * @return Whether the totalCost field is set.
     */
    @java.lang.Override
    public boolean hasTotalCost() {
      return ((bitField0_ & 0x00040000) != 0);
    }
    /**
     * <code>optional double total_cost = 20;</code>
     * @return The totalCost.
     */
    @java.lang.Override
    public double getTotalCost() {
      return totalCost_;
    }

    public static final int QUEUE_NAME_FIELD_NUMBER = 21;
    private volatile java.lang.Object queueName_;
    /**
     * <code>optional string queue_name = 21 [default = "-"];</code>
     * @return Whether the queueName field is set.
     */
    @java.lang.Override
    public boolean hasQueueName() {
      return ((bitField0_ & 0x00080000) != 0);
    }
    /**
     * <code>optional string queue_name = 21 [default = "-"];</code>
     * @return The queueName.
     */
    @java.lang.Override
    public java.lang.String getQueueName() {
      java.lang.Object ref = queueName_;
      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();
        if (bs.isValidUtf8()) {
          queueName_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string queue_name = 21 [default = "-"];</code>
     * @return The bytes for queueName.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getQueueNameBytes() {
      java.lang.Object ref = queueName_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        queueName_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int QUERYID_FIELD_NUMBER = 22;
    private volatile java.lang.Object queryId_;
    /**
     * <code>optional string queryId = 22;</code>
     * @return Whether the queryId field is set.
     */
    @java.lang.Override
    public boolean hasQueryId() {
      return ((bitField0_ & 0x00100000) != 0);
    }
    /**
     * <code>optional string queryId = 22;</code>
     * @return The queryId.
     */
    @java.lang.Override
    public java.lang.String getQueryId() {
      java.lang.Object ref = queryId_;
      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();
        if (bs.isValidUtf8()) {
          queryId_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string queryId = 22;</code>
     * @return The bytes for queryId.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getQueryIdBytes() {
      java.lang.Object ref = queryId_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        queryId_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int AUTOLIMIT_FIELD_NUMBER = 23;
    private int autoLimit_;
    /**
     * <code>optional int32 autoLimit = 23;</code>
     * @return Whether the autoLimit field is set.
     */
    @java.lang.Override
    public boolean hasAutoLimit() {
      return ((bitField0_ & 0x00200000) != 0);
    }
    /**
     * <code>optional int32 autoLimit = 23;</code>
     * @return The autoLimit.
     */
    @java.lang.Override
    public int getAutoLimit() {
      return autoLimit_;
    }

    public static final int SCANNED_PLUGINS_FIELD_NUMBER = 24;
    private com.google.protobuf.LazyStringList scannedPlugins_;
    /**
     * <code>repeated string scanned_plugins = 24;</code>
     * @return A list containing the scannedPlugins.
     */
    public com.google.protobuf.ProtocolStringList
        getScannedPluginsList() {
      return scannedPlugins_;
    }
    /**
     * <code>repeated string scanned_plugins = 24;</code>
     * @return The count of scannedPlugins.
     */
    public int getScannedPluginsCount() {
      return scannedPlugins_.size();
    }
    /**
     * <code>repeated string scanned_plugins = 24;</code>
     * @param index The index of the element to return.
     * @return The scannedPlugins at the given index.
     */
    public java.lang.String getScannedPlugins(int index) {
      return scannedPlugins_.get(index);
    }
    /**
     * <code>repeated string scanned_plugins = 24;</code>
     * @param index The index of the value to return.
     * @return The bytes of the scannedPlugins at the given index.
     */
    public com.google.protobuf.ByteString
        getScannedPluginsBytes(int index) {
      return scannedPlugins_.getByteString(index);
    }

    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 (((bitField0_ & 0x00000001) != 0)) {
        output.writeMessage(1, getId());
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeEnum(2, type_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeInt64(3, start_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        output.writeInt64(4, end_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 5, query_);
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 6, plan_);
      }
      if (((bitField0_ & 0x00000040) != 0)) {
        output.writeMessage(7, getForeman());
      }
      if (((bitField0_ & 0x00000080) != 0)) {
        output.writeEnum(8, state_);
      }
      if (((bitField0_ & 0x00000100) != 0)) {
        output.writeInt32(9, totalFragments_);
      }
      if (((bitField0_ & 0x00000200) != 0)) {
        output.writeInt32(10, finishedFragments_);
      }
      for (int i = 0; i < fragmentProfile_.size(); i++) {
        output.writeMessage(11, fragmentProfile_.get(i));
      }
      if (((bitField0_ & 0x00000400) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 12, user_);
      }
      if (((bitField0_ & 0x00000800) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 13, error_);
      }
      if (((bitField0_ & 0x00001000) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 14, verboseError_);
      }
      if (((bitField0_ & 0x00002000) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 15, errorId_);
      }
      if (((bitField0_ & 0x00004000) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 16, errorNode_);
      }
      if (((bitField0_ & 0x00008000) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 17, optionsJson_);
      }
      if (((bitField0_ & 0x00010000) != 0)) {
        output.writeInt64(18, planEnd_);
      }
      if (((bitField0_ & 0x00020000) != 0)) {
        output.writeInt64(19, queueWaitEnd_);
      }
      if (((bitField0_ & 0x00040000) != 0)) {
        output.writeDouble(20, totalCost_);
      }
      if (((bitField0_ & 0x00080000) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 21, queueName_);
      }
      if (((bitField0_ & 0x00100000) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 22, queryId_);
      }
      if (((bitField0_ & 0x00200000) != 0)) {
        output.writeInt32(23, autoLimit_);
      }
      for (int i = 0; i < scannedPlugins_.size(); i++) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 24, scannedPlugins_.getRaw(i));
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, getId());
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(2, type_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(3, start_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(4, end_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, query_);
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, plan_);
      }
      if (((bitField0_ & 0x00000040) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(7, getForeman());
      }
      if (((bitField0_ & 0x00000080) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(8, state_);
      }
      if (((bitField0_ & 0x00000100) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(9, totalFragments_);
      }
      if (((bitField0_ & 0x00000200) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(10, finishedFragments_);
      }
      for (int i = 0; i < fragmentProfile_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(11, fragmentProfile_.get(i));
      }
      if (((bitField0_ & 0x00000400) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(12, user_);
      }
      if (((bitField0_ & 0x00000800) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(13, error_);
      }
      if (((bitField0_ & 0x00001000) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(14, verboseError_);
      }
      if (((bitField0_ & 0x00002000) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(15, errorId_);
      }
      if (((bitField0_ & 0x00004000) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(16, errorNode_);
      }
      if (((bitField0_ & 0x00008000) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(17, optionsJson_);
      }
      if (((bitField0_ & 0x00010000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(18, planEnd_);
      }
      if (((bitField0_ & 0x00020000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(19, queueWaitEnd_);
      }
      if (((bitField0_ & 0x00040000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeDoubleSize(20, totalCost_);
      }
      if (((bitField0_ & 0x00080000) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(21, queueName_);
      }
      if (((bitField0_ & 0x00100000) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(22, queryId_);
      }
      if (((bitField0_ & 0x00200000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(23, autoLimit_);
      }
      {
        int dataSize = 0;
        for (int i = 0; i < scannedPlugins_.size(); i++) {
          dataSize += computeStringSizeNoTag(scannedPlugins_.getRaw(i));
        }
        size += dataSize;
        size += 2 * getScannedPluginsList().size();
      }
      size += getUnknownFields().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.drill.exec.proto.UserBitShared.QueryProfile)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserBitShared.QueryProfile other = (org.apache.drill.exec.proto.UserBitShared.QueryProfile) obj;

      if (hasId() != other.hasId()) return false;
      if (hasId()) {
        if (!getId()
            .equals(other.getId())) return false;
      }
      if (hasType() != other.hasType()) return false;
      if (hasType()) {
        if (type_ != other.type_) return false;
      }
      if (hasStart() != other.hasStart()) return false;
      if (hasStart()) {
        if (getStart()
            != other.getStart()) return false;
      }
      if (hasEnd() != other.hasEnd()) return false;
      if (hasEnd()) {
        if (getEnd()
            != other.getEnd()) return false;
      }
      if (hasQuery() != other.hasQuery()) return false;
      if (hasQuery()) {
        if (!getQuery()
            .equals(other.getQuery())) return false;
      }
      if (hasPlan() != other.hasPlan()) return false;
      if (hasPlan()) {
        if (!getPlan()
            .equals(other.getPlan())) return false;
      }
      if (hasForeman() != other.hasForeman()) return false;
      if (hasForeman()) {
        if (!getForeman()
            .equals(other.getForeman())) return false;
      }
      if (hasState() != other.hasState()) return false;
      if (hasState()) {
        if (state_ != other.state_) return false;
      }
      if (hasTotalFragments() != other.hasTotalFragments()) return false;
      if (hasTotalFragments()) {
        if (getTotalFragments()
            != other.getTotalFragments()) return false;
      }
      if (hasFinishedFragments() != other.hasFinishedFragments()) return false;
      if (hasFinishedFragments()) {
        if (getFinishedFragments()
            != other.getFinishedFragments()) return false;
      }
      if (!getFragmentProfileList()
          .equals(other.getFragmentProfileList())) return false;
      if (hasUser() != other.hasUser()) return false;
      if (hasUser()) {
        if (!getUser()
            .equals(other.getUser())) return false;
      }
      if (hasError() != other.hasError()) return false;
      if (hasError()) {
        if (!getError()
            .equals(other.getError())) return false;
      }
      if (hasVerboseError() != other.hasVerboseError()) return false;
      if (hasVerboseError()) {
        if (!getVerboseError()
            .equals(other.getVerboseError())) return false;
      }
      if (hasErrorId() != other.hasErrorId()) return false;
      if (hasErrorId()) {
        if (!getErrorId()
            .equals(other.getErrorId())) return false;
      }
      if (hasErrorNode() != other.hasErrorNode()) return false;
      if (hasErrorNode()) {
        if (!getErrorNode()
            .equals(other.getErrorNode())) return false;
      }
      if (hasOptionsJson() != other.hasOptionsJson()) return false;
      if (hasOptionsJson()) {
        if (!getOptionsJson()
            .equals(other.getOptionsJson())) return false;
      }
      if (hasPlanEnd() != other.hasPlanEnd()) return false;
      if (hasPlanEnd()) {
        if (getPlanEnd()
            != other.getPlanEnd()) return false;
      }
      if (hasQueueWaitEnd() != other.hasQueueWaitEnd()) return false;
      if (hasQueueWaitEnd()) {
        if (getQueueWaitEnd()
            != other.getQueueWaitEnd()) return false;
      }
      if (hasTotalCost() != other.hasTotalCost()) return false;
      if (hasTotalCost()) {
        if (java.lang.Double.doubleToLongBits(getTotalCost())
            != java.lang.Double.doubleToLongBits(
                other.getTotalCost())) return false;
      }
      if (hasQueueName() != other.hasQueueName()) return false;
      if (hasQueueName()) {
        if (!getQueueName()
            .equals(other.getQueueName())) return false;
      }
      if (hasQueryId() != other.hasQueryId()) return false;
      if (hasQueryId()) {
        if (!getQueryId()
            .equals(other.getQueryId())) return false;
      }
      if (hasAutoLimit() != other.hasAutoLimit()) return false;
      if (hasAutoLimit()) {
        if (getAutoLimit()
            != other.getAutoLimit()) return false;
      }
      if (!getScannedPluginsList()
          .equals(other.getScannedPluginsList())) return false;
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasId()) {
        hash = (37 * hash) + ID_FIELD_NUMBER;
        hash = (53 * hash) + getId().hashCode();
      }
      if (hasType()) {
        hash = (37 * hash) + TYPE_FIELD_NUMBER;
        hash = (53 * hash) + type_;
      }
      if (hasStart()) {
        hash = (37 * hash) + START_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getStart());
      }
      if (hasEnd()) {
        hash = (37 * hash) + END_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getEnd());
      }
      if (hasQuery()) {
        hash = (37 * hash) + QUERY_FIELD_NUMBER;
        hash = (53 * hash) + getQuery().hashCode();
      }
      if (hasPlan()) {
        hash = (37 * hash) + PLAN_FIELD_NUMBER;
        hash = (53 * hash) + getPlan().hashCode();
      }
      if (hasForeman()) {
        hash = (37 * hash) + FOREMAN_FIELD_NUMBER;
        hash = (53 * hash) + getForeman().hashCode();
      }
      if (hasState()) {
        hash = (37 * hash) + STATE_FIELD_NUMBER;
        hash = (53 * hash) + state_;
      }
      if (hasTotalFragments()) {
        hash = (37 * hash) + TOTAL_FRAGMENTS_FIELD_NUMBER;
        hash = (53 * hash) + getTotalFragments();
      }
      if (hasFinishedFragments()) {
        hash = (37 * hash) + FINISHED_FRAGMENTS_FIELD_NUMBER;
        hash = (53 * hash) + getFinishedFragments();
      }
      if (getFragmentProfileCount() > 0) {
        hash = (37 * hash) + FRAGMENT_PROFILE_FIELD_NUMBER;
        hash = (53 * hash) + getFragmentProfileList().hashCode();
      }
      if (hasUser()) {
        hash = (37 * hash) + USER_FIELD_NUMBER;
        hash = (53 * hash) + getUser().hashCode();
      }
      if (hasError()) {
        hash = (37 * hash) + ERROR_FIELD_NUMBER;
        hash = (53 * hash) + getError().hashCode();
      }
      if (hasVerboseError()) {
        hash = (37 * hash) + VERBOSEERROR_FIELD_NUMBER;
        hash = (53 * hash) + getVerboseError().hashCode();
      }
      if (hasErrorId()) {
        hash = (37 * hash) + ERROR_ID_FIELD_NUMBER;
        hash = (53 * hash) + getErrorId().hashCode();
      }
      if (hasErrorNode()) {
        hash = (37 * hash) + ERROR_NODE_FIELD_NUMBER;
        hash = (53 * hash) + getErrorNode().hashCode();
      }
      if (hasOptionsJson()) {
        hash = (37 * hash) + OPTIONS_JSON_FIELD_NUMBER;
        hash = (53 * hash) + getOptionsJson().hashCode();
      }
      if (hasPlanEnd()) {
        hash = (37 * hash) + PLANEND_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getPlanEnd());
      }
      if (hasQueueWaitEnd()) {
        hash = (37 * hash) + QUEUEWAITEND_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getQueueWaitEnd());
      }
      if (hasTotalCost()) {
        hash = (37 * hash) + TOTAL_COST_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            java.lang.Double.doubleToLongBits(getTotalCost()));
      }
      if (hasQueueName()) {
        hash = (37 * hash) + QUEUE_NAME_FIELD_NUMBER;
        hash = (53 * hash) + getQueueName().hashCode();
      }
      if (hasQueryId()) {
        hash = (37 * hash) + QUERYID_FIELD_NUMBER;
        hash = (53 * hash) + getQueryId().hashCode();
      }
      if (hasAutoLimit()) {
        hash = (37 * hash) + AUTOLIMIT_FIELD_NUMBER;
        hash = (53 * hash) + getAutoLimit();
      }
      if (getScannedPluginsCount() > 0) {
        hash = (37 * hash) + SCANNED_PLUGINS_FIELD_NUMBER;
        hash = (53 * hash) + getScannedPluginsList().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserBitShared.QueryProfile parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryProfile parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryProfile parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryProfile 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.drill.exec.proto.UserBitShared.QueryProfile parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryProfile parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryProfile parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryProfile 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.drill.exec.proto.UserBitShared.QueryProfile parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryProfile 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.drill.exec.proto.UserBitShared.QueryProfile parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.QueryProfile 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.drill.exec.proto.UserBitShared.QueryProfile 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 exec.shared.QueryProfile}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.shared.QueryProfile)
        org.apache.drill.exec.proto.UserBitShared.QueryProfileOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_QueryProfile_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_QueryProfile_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserBitShared.QueryProfile.class, org.apache.drill.exec.proto.UserBitShared.QueryProfile.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserBitShared.QueryProfile.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getIdFieldBuilder();
          getForemanFieldBuilder();
          getFragmentProfileFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        if (idBuilder_ == null) {
          id_ = null;
        } else {
          idBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        type_ = 1;
        bitField0_ = (bitField0_ & ~0x00000002);
        start_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000004);
        end_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000008);
        query_ = "";
        bitField0_ = (bitField0_ & ~0x00000010);
        plan_ = "";
        bitField0_ = (bitField0_ & ~0x00000020);
        if (foremanBuilder_ == null) {
          foreman_ = null;
        } else {
          foremanBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000040);
        state_ = 0;
        bitField0_ = (bitField0_ & ~0x00000080);
        totalFragments_ = 0;
        bitField0_ = (bitField0_ & ~0x00000100);
        finishedFragments_ = 0;
        bitField0_ = (bitField0_ & ~0x00000200);
        if (fragmentProfileBuilder_ == null) {
          fragmentProfile_ = java.util.Collections.emptyList();
        } else {
          fragmentProfile_ = null;
          fragmentProfileBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000400);
        user_ = "-";
        bitField0_ = (bitField0_ & ~0x00000800);
        error_ = "";
        bitField0_ = (bitField0_ & ~0x00001000);
        verboseError_ = "";
        bitField0_ = (bitField0_ & ~0x00002000);
        errorId_ = "";
        bitField0_ = (bitField0_ & ~0x00004000);
        errorNode_ = "";
        bitField0_ = (bitField0_ & ~0x00008000);
        optionsJson_ = "";
        bitField0_ = (bitField0_ & ~0x00010000);
        planEnd_ = 0L;
        bitField0_ = (bitField0_ & ~0x00020000);
        queueWaitEnd_ = 0L;
        bitField0_ = (bitField0_ & ~0x00040000);
        totalCost_ = 0D;
        bitField0_ = (bitField0_ & ~0x00080000);
        queueName_ = "-";
        bitField0_ = (bitField0_ & ~0x00100000);
        queryId_ = "";
        bitField0_ = (bitField0_ & ~0x00200000);
        autoLimit_ = 0;
        bitField0_ = (bitField0_ & ~0x00400000);
        scannedPlugins_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        bitField0_ = (bitField0_ & ~0x00800000);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_QueryProfile_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.QueryProfile getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserBitShared.QueryProfile.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.QueryProfile build() {
        org.apache.drill.exec.proto.UserBitShared.QueryProfile result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.QueryProfile buildPartial() {
        org.apache.drill.exec.proto.UserBitShared.QueryProfile result = new org.apache.drill.exec.proto.UserBitShared.QueryProfile(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          if (idBuilder_ == null) {
            result.id_ = id_;
          } else {
            result.id_ = idBuilder_.build();
          }
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          to_bitField0_ |= 0x00000002;
        }
        result.type_ = type_;
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.start_ = start_;
          to_bitField0_ |= 0x00000004;
        }
        if (((from_bitField0_ & 0x00000008) != 0)) {
          result.end_ = end_;
          to_bitField0_ |= 0x00000008;
        }
        if (((from_bitField0_ & 0x00000010) != 0)) {
          to_bitField0_ |= 0x00000010;
        }
        result.query_ = query_;
        if (((from_bitField0_ & 0x00000020) != 0)) {
          to_bitField0_ |= 0x00000020;
        }
        result.plan_ = plan_;
        if (((from_bitField0_ & 0x00000040) != 0)) {
          if (foremanBuilder_ == null) {
            result.foreman_ = foreman_;
          } else {
            result.foreman_ = foremanBuilder_.build();
          }
          to_bitField0_ |= 0x00000040;
        }
        if (((from_bitField0_ & 0x00000080) != 0)) {
          to_bitField0_ |= 0x00000080;
        }
        result.state_ = state_;
        if (((from_bitField0_ & 0x00000100) != 0)) {
          result.totalFragments_ = totalFragments_;
          to_bitField0_ |= 0x00000100;
        }
        if (((from_bitField0_ & 0x00000200) != 0)) {
          result.finishedFragments_ = finishedFragments_;
          to_bitField0_ |= 0x00000200;
        }
        if (fragmentProfileBuilder_ == null) {
          if (((bitField0_ & 0x00000400) != 0)) {
            fragmentProfile_ = java.util.Collections.unmodifiableList(fragmentProfile_);
            bitField0_ = (bitField0_ & ~0x00000400);
          }
          result.fragmentProfile_ = fragmentProfile_;
        } else {
          result.fragmentProfile_ = fragmentProfileBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000800) != 0)) {
          to_bitField0_ |= 0x00000400;
        }
        result.user_ = user_;
        if (((from_bitField0_ & 0x00001000) != 0)) {
          to_bitField0_ |= 0x00000800;
        }
        result.error_ = error_;
        if (((from_bitField0_ & 0x00002000) != 0)) {
          to_bitField0_ |= 0x00001000;
        }
        result.verboseError_ = verboseError_;
        if (((from_bitField0_ & 0x00004000) != 0)) {
          to_bitField0_ |= 0x00002000;
        }
        result.errorId_ = errorId_;
        if (((from_bitField0_ & 0x00008000) != 0)) {
          to_bitField0_ |= 0x00004000;
        }
        result.errorNode_ = errorNode_;
        if (((from_bitField0_ & 0x00010000) != 0)) {
          to_bitField0_ |= 0x00008000;
        }
        result.optionsJson_ = optionsJson_;
        if (((from_bitField0_ & 0x00020000) != 0)) {
          result.planEnd_ = planEnd_;
          to_bitField0_ |= 0x00010000;
        }
        if (((from_bitField0_ & 0x00040000) != 0)) {
          result.queueWaitEnd_ = queueWaitEnd_;
          to_bitField0_ |= 0x00020000;
        }
        if (((from_bitField0_ & 0x00080000) != 0)) {
          result.totalCost_ = totalCost_;
          to_bitField0_ |= 0x00040000;
        }
        if (((from_bitField0_ & 0x00100000) != 0)) {
          to_bitField0_ |= 0x00080000;
        }
        result.queueName_ = queueName_;
        if (((from_bitField0_ & 0x00200000) != 0)) {
          to_bitField0_ |= 0x00100000;
        }
        result.queryId_ = queryId_;
        if (((from_bitField0_ & 0x00400000) != 0)) {
          result.autoLimit_ = autoLimit_;
          to_bitField0_ |= 0x00200000;
        }
        if (((bitField0_ & 0x00800000) != 0)) {
          scannedPlugins_ = scannedPlugins_.getUnmodifiableView();
          bitField0_ = (bitField0_ & ~0x00800000);
        }
        result.scannedPlugins_ = scannedPlugins_;
        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.drill.exec.proto.UserBitShared.QueryProfile) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.QueryProfile)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.QueryProfile other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.QueryProfile.getDefaultInstance()) return this;
        if (other.hasId()) {
          mergeId(other.getId());
        }
        if (other.hasType()) {
          setType(other.getType());
        }
        if (other.hasStart()) {
          setStart(other.getStart());
        }
        if (other.hasEnd()) {
          setEnd(other.getEnd());
        }
        if (other.hasQuery()) {
          bitField0_ |= 0x00000010;
          query_ = other.query_;
          onChanged();
        }
        if (other.hasPlan()) {
          bitField0_ |= 0x00000020;
          plan_ = other.plan_;
          onChanged();
        }
        if (other.hasForeman()) {
          mergeForeman(other.getForeman());
        }
        if (other.hasState()) {
          setState(other.getState());
        }
        if (other.hasTotalFragments()) {
          setTotalFragments(other.getTotalFragments());
        }
        if (other.hasFinishedFragments()) {
          setFinishedFragments(other.getFinishedFragments());
        }
        if (fragmentProfileBuilder_ == null) {
          if (!other.fragmentProfile_.isEmpty()) {
            if (fragmentProfile_.isEmpty()) {
              fragmentProfile_ = other.fragmentProfile_;
              bitField0_ = (bitField0_ & ~0x00000400);
            } else {
              ensureFragmentProfileIsMutable();
              fragmentProfile_.addAll(other.fragmentProfile_);
            }
            onChanged();
          }
        } else {
          if (!other.fragmentProfile_.isEmpty()) {
            if (fragmentProfileBuilder_.isEmpty()) {
              fragmentProfileBuilder_.dispose();
              fragmentProfileBuilder_ = null;
              fragmentProfile_ = other.fragmentProfile_;
              bitField0_ = (bitField0_ & ~0x00000400);
              fragmentProfileBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getFragmentProfileFieldBuilder() : null;
            } else {
              fragmentProfileBuilder_.addAllMessages(other.fragmentProfile_);
            }
          }
        }
        if (other.hasUser()) {
          bitField0_ |= 0x00000800;
          user_ = other.user_;
          onChanged();
        }
        if (other.hasError()) {
          bitField0_ |= 0x00001000;
          error_ = other.error_;
          onChanged();
        }
        if (other.hasVerboseError()) {
          bitField0_ |= 0x00002000;
          verboseError_ = other.verboseError_;
          onChanged();
        }
        if (other.hasErrorId()) {
          bitField0_ |= 0x00004000;
          errorId_ = other.errorId_;
          onChanged();
        }
        if (other.hasErrorNode()) {
          bitField0_ |= 0x00008000;
          errorNode_ = other.errorNode_;
          onChanged();
        }
        if (other.hasOptionsJson()) {
          bitField0_ |= 0x00010000;
          optionsJson_ = other.optionsJson_;
          onChanged();
        }
        if (other.hasPlanEnd()) {
          setPlanEnd(other.getPlanEnd());
        }
        if (other.hasQueueWaitEnd()) {
          setQueueWaitEnd(other.getQueueWaitEnd());
        }
        if (other.hasTotalCost()) {
          setTotalCost(other.getTotalCost());
        }
        if (other.hasQueueName()) {
          bitField0_ |= 0x00100000;
          queueName_ = other.queueName_;
          onChanged();
        }
        if (other.hasQueryId()) {
          bitField0_ |= 0x00200000;
          queryId_ = other.queryId_;
          onChanged();
        }
        if (other.hasAutoLimit()) {
          setAutoLimit(other.getAutoLimit());
        }
        if (!other.scannedPlugins_.isEmpty()) {
          if (scannedPlugins_.isEmpty()) {
            scannedPlugins_ = other.scannedPlugins_;
            bitField0_ = (bitField0_ & ~0x00800000);
          } else {
            ensureScannedPluginsIsMutable();
            scannedPlugins_.addAll(other.scannedPlugins_);
          }
          onChanged();
        }
        this.mergeUnknownFields(other.getUnknownFields());
        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 {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                input.readMessage(
                    getIdFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 16: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserBitShared.QueryType tmpValue =
                    org.apache.drill.exec.proto.UserBitShared.QueryType.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(2, tmpRaw);
                } else {
                  type_ = tmpRaw;
                  bitField0_ |= 0x00000002;
                }
                break;
              } // case 16
              case 24: {
                start_ = input.readInt64();
                bitField0_ |= 0x00000004;
                break;
              } // case 24
              case 32: {
                end_ = input.readInt64();
                bitField0_ |= 0x00000008;
                break;
              } // case 32
              case 42: {
                query_ = input.readBytes();
                bitField0_ |= 0x00000010;
                break;
              } // case 42
              case 50: {
                plan_ = input.readBytes();
                bitField0_ |= 0x00000020;
                break;
              } // case 50
              case 58: {
                input.readMessage(
                    getForemanFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000040;
                break;
              } // case 58
              case 64: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState tmpValue =
                    org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(8, tmpRaw);
                } else {
                  state_ = tmpRaw;
                  bitField0_ |= 0x00000080;
                }
                break;
              } // case 64
              case 72: {
                totalFragments_ = input.readInt32();
                bitField0_ |= 0x00000100;
                break;
              } // case 72
              case 80: {
                finishedFragments_ = input.readInt32();
                bitField0_ |= 0x00000200;
                break;
              } // case 80
              case 90: {
                org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile m =
                    input.readMessage(
                        org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile.PARSER,
                        extensionRegistry);
                if (fragmentProfileBuilder_ == null) {
                  ensureFragmentProfileIsMutable();
                  fragmentProfile_.add(m);
                } else {
                  fragmentProfileBuilder_.addMessage(m);
                }
                break;
              } // case 90
              case 98: {
                user_ = input.readBytes();
                bitField0_ |= 0x00000800;
                break;
              } // case 98
              case 106: {
                error_ = input.readBytes();
                bitField0_ |= 0x00001000;
                break;
              } // case 106
              case 114: {
                verboseError_ = input.readBytes();
                bitField0_ |= 0x00002000;
                break;
              } // case 114
              case 122: {
                errorId_ = input.readBytes();
                bitField0_ |= 0x00004000;
                break;
              } // case 122
              case 130: {
                errorNode_ = input.readBytes();
                bitField0_ |= 0x00008000;
                break;
              } // case 130
              case 138: {
                optionsJson_ = input.readBytes();
                bitField0_ |= 0x00010000;
                break;
              } // case 138
              case 144: {
                planEnd_ = input.readInt64();
                bitField0_ |= 0x00020000;
                break;
              } // case 144
              case 152: {
                queueWaitEnd_ = input.readInt64();
                bitField0_ |= 0x00040000;
                break;
              } // case 152
              case 161: {
                totalCost_ = input.readDouble();
                bitField0_ |= 0x00080000;
                break;
              } // case 161
              case 170: {
                queueName_ = input.readBytes();
                bitField0_ |= 0x00100000;
                break;
              } // case 170
              case 178: {
                queryId_ = input.readBytes();
                bitField0_ |= 0x00200000;
                break;
              } // case 178
              case 184: {
                autoLimit_ = input.readInt32();
                bitField0_ |= 0x00400000;
                break;
              } // case 184
              case 194: {
                com.google.protobuf.ByteString bs = input.readBytes();
                ensureScannedPluginsIsMutable();
                scannedPlugins_.add(bs);
                break;
              } // case 194
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private org.apache.drill.exec.proto.UserBitShared.QueryId id_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.QueryId, org.apache.drill.exec.proto.UserBitShared.QueryId.Builder, org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder> idBuilder_;
      /**
       * <code>optional .exec.shared.QueryId id = 1;</code>
       * @return Whether the id field is set.
       */
      public boolean hasId() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .exec.shared.QueryId id = 1;</code>
       * @return The id.
       */
      public org.apache.drill.exec.proto.UserBitShared.QueryId getId() {
        if (idBuilder_ == null) {
          return id_ == null ? org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance() : id_;
        } else {
          return idBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.shared.QueryId id = 1;</code>
       */
      public Builder setId(org.apache.drill.exec.proto.UserBitShared.QueryId value) {
        if (idBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          id_ = value;
          onChanged();
        } else {
          idBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryId id = 1;</code>
       */
      public Builder setId(
          org.apache.drill.exec.proto.UserBitShared.QueryId.Builder builderForValue) {
        if (idBuilder_ == null) {
          id_ = builderForValue.build();
          onChanged();
        } else {
          idBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryId id = 1;</code>
       */
      public Builder mergeId(org.apache.drill.exec.proto.UserBitShared.QueryId value) {
        if (idBuilder_ == null) {
          if (((bitField0_ & 0x00000001) != 0) &&
              id_ != null &&
              id_ != org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance()) {
            id_ =
              org.apache.drill.exec.proto.UserBitShared.QueryId.newBuilder(id_).mergeFrom(value).buildPartial();
          } else {
            id_ = value;
          }
          onChanged();
        } else {
          idBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryId id = 1;</code>
       */
      public Builder clearId() {
        if (idBuilder_ == null) {
          id_ = null;
          onChanged();
        } else {
          idBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryId id = 1;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.QueryId.Builder getIdBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getIdFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.shared.QueryId id = 1;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder getIdOrBuilder() {
        if (idBuilder_ != null) {
          return idBuilder_.getMessageOrBuilder();
        } else {
          return id_ == null ?
              org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance() : id_;
        }
      }
      /**
       * <code>optional .exec.shared.QueryId id = 1;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.QueryId, org.apache.drill.exec.proto.UserBitShared.QueryId.Builder, org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder> 
          getIdFieldBuilder() {
        if (idBuilder_ == null) {
          idBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.QueryId, org.apache.drill.exec.proto.UserBitShared.QueryId.Builder, org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder>(
                  getId(),
                  getParentForChildren(),
                  isClean());
          id_ = null;
        }
        return idBuilder_;
      }

      private int type_ = 1;
      /**
       * <code>optional .exec.shared.QueryType type = 2;</code>
       * @return Whether the type field is set.
       */
      @java.lang.Override public boolean hasType() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional .exec.shared.QueryType type = 2;</code>
       * @return The type.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.QueryType getType() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserBitShared.QueryType result = org.apache.drill.exec.proto.UserBitShared.QueryType.valueOf(type_);
        return result == null ? org.apache.drill.exec.proto.UserBitShared.QueryType.SQL : result;
      }
      /**
       * <code>optional .exec.shared.QueryType type = 2;</code>
       * @param value The type to set.
       * @return This builder for chaining.
       */
      public Builder setType(org.apache.drill.exec.proto.UserBitShared.QueryType value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000002;
        type_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryType type = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearType() {
        bitField0_ = (bitField0_ & ~0x00000002);
        type_ = 1;
        onChanged();
        return this;
      }

      private long start_ ;
      /**
       * <code>optional int64 start = 3;</code>
       * @return Whether the start field is set.
       */
      @java.lang.Override
      public boolean hasStart() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional int64 start = 3;</code>
       * @return The start.
       */
      @java.lang.Override
      public long getStart() {
        return start_;
      }
      /**
       * <code>optional int64 start = 3;</code>
       * @param value The start to set.
       * @return This builder for chaining.
       */
      public Builder setStart(long value) {
        bitField0_ |= 0x00000004;
        start_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 start = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearStart() {
        bitField0_ = (bitField0_ & ~0x00000004);
        start_ = 0L;
        onChanged();
        return this;
      }

      private long end_ ;
      /**
       * <code>optional int64 end = 4;</code>
       * @return Whether the end field is set.
       */
      @java.lang.Override
      public boolean hasEnd() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <code>optional int64 end = 4;</code>
       * @return The end.
       */
      @java.lang.Override
      public long getEnd() {
        return end_;
      }
      /**
       * <code>optional int64 end = 4;</code>
       * @param value The end to set.
       * @return This builder for chaining.
       */
      public Builder setEnd(long value) {
        bitField0_ |= 0x00000008;
        end_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 end = 4;</code>
       * @return This builder for chaining.
       */
      public Builder clearEnd() {
        bitField0_ = (bitField0_ & ~0x00000008);
        end_ = 0L;
        onChanged();
        return this;
      }

      private java.lang.Object query_ = "";
      /**
       * <code>optional string query = 5;</code>
       * @return Whether the query field is set.
       */
      public boolean hasQuery() {
        return ((bitField0_ & 0x00000010) != 0);
      }
      /**
       * <code>optional string query = 5;</code>
       * @return The query.
       */
      public java.lang.String getQuery() {
        java.lang.Object ref = query_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            query_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string query = 5;</code>
       * @return The bytes for query.
       */
      public com.google.protobuf.ByteString
          getQueryBytes() {
        java.lang.Object ref = query_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          query_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string query = 5;</code>
       * @param value The query to set.
       * @return This builder for chaining.
       */
      public Builder setQuery(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000010;
        query_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string query = 5;</code>
       * @return This builder for chaining.
       */
      public Builder clearQuery() {
        bitField0_ = (bitField0_ & ~0x00000010);
        query_ = getDefaultInstance().getQuery();
        onChanged();
        return this;
      }
      /**
       * <code>optional string query = 5;</code>
       * @param value The bytes for query to set.
       * @return This builder for chaining.
       */
      public Builder setQueryBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000010;
        query_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object plan_ = "";
      /**
       * <code>optional string plan = 6;</code>
       * @return Whether the plan field is set.
       */
      public boolean hasPlan() {
        return ((bitField0_ & 0x00000020) != 0);
      }
      /**
       * <code>optional string plan = 6;</code>
       * @return The plan.
       */
      public java.lang.String getPlan() {
        java.lang.Object ref = plan_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            plan_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string plan = 6;</code>
       * @return The bytes for plan.
       */
      public com.google.protobuf.ByteString
          getPlanBytes() {
        java.lang.Object ref = plan_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          plan_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string plan = 6;</code>
       * @param value The plan to set.
       * @return This builder for chaining.
       */
      public Builder setPlan(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000020;
        plan_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string plan = 6;</code>
       * @return This builder for chaining.
       */
      public Builder clearPlan() {
        bitField0_ = (bitField0_ & ~0x00000020);
        plan_ = getDefaultInstance().getPlan();
        onChanged();
        return this;
      }
      /**
       * <code>optional string plan = 6;</code>
       * @param value The bytes for plan to set.
       * @return This builder for chaining.
       */
      public Builder setPlanBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000020;
        plan_ = value;
        onChanged();
        return this;
      }

      private org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint foreman_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint, org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder, org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder> foremanBuilder_;
      /**
       * <code>optional .exec.DrillbitEndpoint foreman = 7;</code>
       * @return Whether the foreman field is set.
       */
      public boolean hasForeman() {
        return ((bitField0_ & 0x00000040) != 0);
      }
      /**
       * <code>optional .exec.DrillbitEndpoint foreman = 7;</code>
       * @return The foreman.
       */
      public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint getForeman() {
        if (foremanBuilder_ == null) {
          return foreman_ == null ? org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance() : foreman_;
        } else {
          return foremanBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.DrillbitEndpoint foreman = 7;</code>
       */
      public Builder setForeman(org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint value) {
        if (foremanBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          foreman_ = value;
          onChanged();
        } else {
          foremanBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000040;
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint foreman = 7;</code>
       */
      public Builder setForeman(
          org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder builderForValue) {
        if (foremanBuilder_ == null) {
          foreman_ = builderForValue.build();
          onChanged();
        } else {
          foremanBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000040;
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint foreman = 7;</code>
       */
      public Builder mergeForeman(org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint value) {
        if (foremanBuilder_ == null) {
          if (((bitField0_ & 0x00000040) != 0) &&
              foreman_ != null &&
              foreman_ != org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance()) {
            foreman_ =
              org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.newBuilder(foreman_).mergeFrom(value).buildPartial();
          } else {
            foreman_ = value;
          }
          onChanged();
        } else {
          foremanBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000040;
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint foreman = 7;</code>
       */
      public Builder clearForeman() {
        if (foremanBuilder_ == null) {
          foreman_ = null;
          onChanged();
        } else {
          foremanBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000040);
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint foreman = 7;</code>
       */
      public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder getForemanBuilder() {
        bitField0_ |= 0x00000040;
        onChanged();
        return getForemanFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.DrillbitEndpoint foreman = 7;</code>
       */
      public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder getForemanOrBuilder() {
        if (foremanBuilder_ != null) {
          return foremanBuilder_.getMessageOrBuilder();
        } else {
          return foreman_ == null ?
              org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance() : foreman_;
        }
      }
      /**
       * <code>optional .exec.DrillbitEndpoint foreman = 7;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint, org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder, org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder> 
          getForemanFieldBuilder() {
        if (foremanBuilder_ == null) {
          foremanBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint, org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder, org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder>(
                  getForeman(),
                  getParentForChildren(),
                  isClean());
          foreman_ = null;
        }
        return foremanBuilder_;
      }

      private int state_ = 0;
      /**
       * <code>optional .exec.shared.QueryResult.QueryState state = 8;</code>
       * @return Whether the state field is set.
       */
      @java.lang.Override public boolean hasState() {
        return ((bitField0_ & 0x00000080) != 0);
      }
      /**
       * <code>optional .exec.shared.QueryResult.QueryState state = 8;</code>
       * @return The state.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState getState() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState result = org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.valueOf(state_);
        return result == null ? org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.STARTING : result;
      }
      /**
       * <code>optional .exec.shared.QueryResult.QueryState state = 8;</code>
       * @param value The state to set.
       * @return This builder for chaining.
       */
      public Builder setState(org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000080;
        state_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryResult.QueryState state = 8;</code>
       * @return This builder for chaining.
       */
      public Builder clearState() {
        bitField0_ = (bitField0_ & ~0x00000080);
        state_ = 0;
        onChanged();
        return this;
      }

      private int totalFragments_ ;
      /**
       * <code>optional int32 total_fragments = 9;</code>
       * @return Whether the totalFragments field is set.
       */
      @java.lang.Override
      public boolean hasTotalFragments() {
        return ((bitField0_ & 0x00000100) != 0);
      }
      /**
       * <code>optional int32 total_fragments = 9;</code>
       * @return The totalFragments.
       */
      @java.lang.Override
      public int getTotalFragments() {
        return totalFragments_;
      }
      /**
       * <code>optional int32 total_fragments = 9;</code>
       * @param value The totalFragments to set.
       * @return This builder for chaining.
       */
      public Builder setTotalFragments(int value) {
        bitField0_ |= 0x00000100;
        totalFragments_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 total_fragments = 9;</code>
       * @return This builder for chaining.
       */
      public Builder clearTotalFragments() {
        bitField0_ = (bitField0_ & ~0x00000100);
        totalFragments_ = 0;
        onChanged();
        return this;
      }

      private int finishedFragments_ ;
      /**
       * <code>optional int32 finished_fragments = 10;</code>
       * @return Whether the finishedFragments field is set.
       */
      @java.lang.Override
      public boolean hasFinishedFragments() {
        return ((bitField0_ & 0x00000200) != 0);
      }
      /**
       * <code>optional int32 finished_fragments = 10;</code>
       * @return The finishedFragments.
       */
      @java.lang.Override
      public int getFinishedFragments() {
        return finishedFragments_;
      }
      /**
       * <code>optional int32 finished_fragments = 10;</code>
       * @param value The finishedFragments to set.
       * @return This builder for chaining.
       */
      public Builder setFinishedFragments(int value) {
        bitField0_ |= 0x00000200;
        finishedFragments_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 finished_fragments = 10;</code>
       * @return This builder for chaining.
       */
      public Builder clearFinishedFragments() {
        bitField0_ = (bitField0_ & ~0x00000200);
        finishedFragments_ = 0;
        onChanged();
        return this;
      }

      private java.util.List<org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile> fragmentProfile_ =
        java.util.Collections.emptyList();
      private void ensureFragmentProfileIsMutable() {
        if (!((bitField0_ & 0x00000400) != 0)) {
          fragmentProfile_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile>(fragmentProfile_);
          bitField0_ |= 0x00000400;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile, org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile.Builder, org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfileOrBuilder> fragmentProfileBuilder_;

      /**
       * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile> getFragmentProfileList() {
        if (fragmentProfileBuilder_ == null) {
          return java.util.Collections.unmodifiableList(fragmentProfile_);
        } else {
          return fragmentProfileBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
       */
      public int getFragmentProfileCount() {
        if (fragmentProfileBuilder_ == null) {
          return fragmentProfile_.size();
        } else {
          return fragmentProfileBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile getFragmentProfile(int index) {
        if (fragmentProfileBuilder_ == null) {
          return fragmentProfile_.get(index);
        } else {
          return fragmentProfileBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
       */
      public Builder setFragmentProfile(
          int index, org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile value) {
        if (fragmentProfileBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureFragmentProfileIsMutable();
          fragmentProfile_.set(index, value);
          onChanged();
        } else {
          fragmentProfileBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
       */
      public Builder setFragmentProfile(
          int index, org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile.Builder builderForValue) {
        if (fragmentProfileBuilder_ == null) {
          ensureFragmentProfileIsMutable();
          fragmentProfile_.set(index, builderForValue.build());
          onChanged();
        } else {
          fragmentProfileBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
       */
      public Builder addFragmentProfile(org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile value) {
        if (fragmentProfileBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureFragmentProfileIsMutable();
          fragmentProfile_.add(value);
          onChanged();
        } else {
          fragmentProfileBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
       */
      public Builder addFragmentProfile(
          int index, org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile value) {
        if (fragmentProfileBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureFragmentProfileIsMutable();
          fragmentProfile_.add(index, value);
          onChanged();
        } else {
          fragmentProfileBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
       */
      public Builder addFragmentProfile(
          org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile.Builder builderForValue) {
        if (fragmentProfileBuilder_ == null) {
          ensureFragmentProfileIsMutable();
          fragmentProfile_.add(builderForValue.build());
          onChanged();
        } else {
          fragmentProfileBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
       */
      public Builder addFragmentProfile(
          int index, org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile.Builder builderForValue) {
        if (fragmentProfileBuilder_ == null) {
          ensureFragmentProfileIsMutable();
          fragmentProfile_.add(index, builderForValue.build());
          onChanged();
        } else {
          fragmentProfileBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
       */
      public Builder addAllFragmentProfile(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile> values) {
        if (fragmentProfileBuilder_ == null) {
          ensureFragmentProfileIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, fragmentProfile_);
          onChanged();
        } else {
          fragmentProfileBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
       */
      public Builder clearFragmentProfile() {
        if (fragmentProfileBuilder_ == null) {
          fragmentProfile_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000400);
          onChanged();
        } else {
          fragmentProfileBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
       */
      public Builder removeFragmentProfile(int index) {
        if (fragmentProfileBuilder_ == null) {
          ensureFragmentProfileIsMutable();
          fragmentProfile_.remove(index);
          onChanged();
        } else {
          fragmentProfileBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile.Builder getFragmentProfileBuilder(
          int index) {
        return getFragmentProfileFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfileOrBuilder getFragmentProfileOrBuilder(
          int index) {
        if (fragmentProfileBuilder_ == null) {
          return fragmentProfile_.get(index);  } else {
          return fragmentProfileBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
       */
      public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfileOrBuilder> 
           getFragmentProfileOrBuilderList() {
        if (fragmentProfileBuilder_ != null) {
          return fragmentProfileBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(fragmentProfile_);
        }
      }
      /**
       * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile.Builder addFragmentProfileBuilder() {
        return getFragmentProfileFieldBuilder().addBuilder(
            org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile.Builder addFragmentProfileBuilder(
          int index) {
        return getFragmentProfileFieldBuilder().addBuilder(
            index, org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile.Builder> 
           getFragmentProfileBuilderList() {
        return getFragmentProfileFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile, org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile.Builder, org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfileOrBuilder> 
          getFragmentProfileFieldBuilder() {
        if (fragmentProfileBuilder_ == null) {
          fragmentProfileBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile, org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile.Builder, org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfileOrBuilder>(
                  fragmentProfile_,
                  ((bitField0_ & 0x00000400) != 0),
                  getParentForChildren(),
                  isClean());
          fragmentProfile_ = null;
        }
        return fragmentProfileBuilder_;
      }

      private java.lang.Object user_ = "-";
      /**
       * <code>optional string user = 12 [default = "-"];</code>
       * @return Whether the user field is set.
       */
      public boolean hasUser() {
        return ((bitField0_ & 0x00000800) != 0);
      }
      /**
       * <code>optional string user = 12 [default = "-"];</code>
       * @return The user.
       */
      public java.lang.String getUser() {
        java.lang.Object ref = user_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            user_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string user = 12 [default = "-"];</code>
       * @return The bytes for user.
       */
      public com.google.protobuf.ByteString
          getUserBytes() {
        java.lang.Object ref = user_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          user_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string user = 12 [default = "-"];</code>
       * @param value The user to set.
       * @return This builder for chaining.
       */
      public Builder setUser(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000800;
        user_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string user = 12 [default = "-"];</code>
       * @return This builder for chaining.
       */
      public Builder clearUser() {
        bitField0_ = (bitField0_ & ~0x00000800);
        user_ = getDefaultInstance().getUser();
        onChanged();
        return this;
      }
      /**
       * <code>optional string user = 12 [default = "-"];</code>
       * @param value The bytes for user to set.
       * @return This builder for chaining.
       */
      public Builder setUserBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000800;
        user_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object error_ = "";
      /**
       * <code>optional string error = 13;</code>
       * @return Whether the error field is set.
       */
      public boolean hasError() {
        return ((bitField0_ & 0x00001000) != 0);
      }
      /**
       * <code>optional string error = 13;</code>
       * @return The error.
       */
      public java.lang.String getError() {
        java.lang.Object ref = error_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            error_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string error = 13;</code>
       * @return The bytes for error.
       */
      public com.google.protobuf.ByteString
          getErrorBytes() {
        java.lang.Object ref = error_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          error_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string error = 13;</code>
       * @param value The error to set.
       * @return This builder for chaining.
       */
      public Builder setError(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00001000;
        error_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string error = 13;</code>
       * @return This builder for chaining.
       */
      public Builder clearError() {
        bitField0_ = (bitField0_ & ~0x00001000);
        error_ = getDefaultInstance().getError();
        onChanged();
        return this;
      }
      /**
       * <code>optional string error = 13;</code>
       * @param value The bytes for error to set.
       * @return This builder for chaining.
       */
      public Builder setErrorBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00001000;
        error_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object verboseError_ = "";
      /**
       * <code>optional string verboseError = 14;</code>
       * @return Whether the verboseError field is set.
       */
      public boolean hasVerboseError() {
        return ((bitField0_ & 0x00002000) != 0);
      }
      /**
       * <code>optional string verboseError = 14;</code>
       * @return The verboseError.
       */
      public java.lang.String getVerboseError() {
        java.lang.Object ref = verboseError_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            verboseError_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string verboseError = 14;</code>
       * @return The bytes for verboseError.
       */
      public com.google.protobuf.ByteString
          getVerboseErrorBytes() {
        java.lang.Object ref = verboseError_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          verboseError_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string verboseError = 14;</code>
       * @param value The verboseError to set.
       * @return This builder for chaining.
       */
      public Builder setVerboseError(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00002000;
        verboseError_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string verboseError = 14;</code>
       * @return This builder for chaining.
       */
      public Builder clearVerboseError() {
        bitField0_ = (bitField0_ & ~0x00002000);
        verboseError_ = getDefaultInstance().getVerboseError();
        onChanged();
        return this;
      }
      /**
       * <code>optional string verboseError = 14;</code>
       * @param value The bytes for verboseError to set.
       * @return This builder for chaining.
       */
      public Builder setVerboseErrorBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00002000;
        verboseError_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object errorId_ = "";
      /**
       * <code>optional string error_id = 15;</code>
       * @return Whether the errorId field is set.
       */
      public boolean hasErrorId() {
        return ((bitField0_ & 0x00004000) != 0);
      }
      /**
       * <code>optional string error_id = 15;</code>
       * @return The errorId.
       */
      public java.lang.String getErrorId() {
        java.lang.Object ref = errorId_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            errorId_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string error_id = 15;</code>
       * @return The bytes for errorId.
       */
      public com.google.protobuf.ByteString
          getErrorIdBytes() {
        java.lang.Object ref = errorId_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          errorId_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string error_id = 15;</code>
       * @param value The errorId to set.
       * @return This builder for chaining.
       */
      public Builder setErrorId(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00004000;
        errorId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string error_id = 15;</code>
       * @return This builder for chaining.
       */
      public Builder clearErrorId() {
        bitField0_ = (bitField0_ & ~0x00004000);
        errorId_ = getDefaultInstance().getErrorId();
        onChanged();
        return this;
      }
      /**
       * <code>optional string error_id = 15;</code>
       * @param value The bytes for errorId to set.
       * @return This builder for chaining.
       */
      public Builder setErrorIdBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00004000;
        errorId_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object errorNode_ = "";
      /**
       * <code>optional string error_node = 16;</code>
       * @return Whether the errorNode field is set.
       */
      public boolean hasErrorNode() {
        return ((bitField0_ & 0x00008000) != 0);
      }
      /**
       * <code>optional string error_node = 16;</code>
       * @return The errorNode.
       */
      public java.lang.String getErrorNode() {
        java.lang.Object ref = errorNode_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            errorNode_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string error_node = 16;</code>
       * @return The bytes for errorNode.
       */
      public com.google.protobuf.ByteString
          getErrorNodeBytes() {
        java.lang.Object ref = errorNode_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          errorNode_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string error_node = 16;</code>
       * @param value The errorNode to set.
       * @return This builder for chaining.
       */
      public Builder setErrorNode(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00008000;
        errorNode_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string error_node = 16;</code>
       * @return This builder for chaining.
       */
      public Builder clearErrorNode() {
        bitField0_ = (bitField0_ & ~0x00008000);
        errorNode_ = getDefaultInstance().getErrorNode();
        onChanged();
        return this;
      }
      /**
       * <code>optional string error_node = 16;</code>
       * @param value The bytes for errorNode to set.
       * @return This builder for chaining.
       */
      public Builder setErrorNodeBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00008000;
        errorNode_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object optionsJson_ = "";
      /**
       * <code>optional string options_json = 17;</code>
       * @return Whether the optionsJson field is set.
       */
      public boolean hasOptionsJson() {
        return ((bitField0_ & 0x00010000) != 0);
      }
      /**
       * <code>optional string options_json = 17;</code>
       * @return The optionsJson.
       */
      public java.lang.String getOptionsJson() {
        java.lang.Object ref = optionsJson_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            optionsJson_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string options_json = 17;</code>
       * @return The bytes for optionsJson.
       */
      public com.google.protobuf.ByteString
          getOptionsJsonBytes() {
        java.lang.Object ref = optionsJson_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          optionsJson_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string options_json = 17;</code>
       * @param value The optionsJson to set.
       * @return This builder for chaining.
       */
      public Builder setOptionsJson(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00010000;
        optionsJson_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string options_json = 17;</code>
       * @return This builder for chaining.
       */
      public Builder clearOptionsJson() {
        bitField0_ = (bitField0_ & ~0x00010000);
        optionsJson_ = getDefaultInstance().getOptionsJson();
        onChanged();
        return this;
      }
      /**
       * <code>optional string options_json = 17;</code>
       * @param value The bytes for optionsJson to set.
       * @return This builder for chaining.
       */
      public Builder setOptionsJsonBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00010000;
        optionsJson_ = value;
        onChanged();
        return this;
      }

      private long planEnd_ ;
      /**
       * <code>optional int64 planEnd = 18;</code>
       * @return Whether the planEnd field is set.
       */
      @java.lang.Override
      public boolean hasPlanEnd() {
        return ((bitField0_ & 0x00020000) != 0);
      }
      /**
       * <code>optional int64 planEnd = 18;</code>
       * @return The planEnd.
       */
      @java.lang.Override
      public long getPlanEnd() {
        return planEnd_;
      }
      /**
       * <code>optional int64 planEnd = 18;</code>
       * @param value The planEnd to set.
       * @return This builder for chaining.
       */
      public Builder setPlanEnd(long value) {
        bitField0_ |= 0x00020000;
        planEnd_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 planEnd = 18;</code>
       * @return This builder for chaining.
       */
      public Builder clearPlanEnd() {
        bitField0_ = (bitField0_ & ~0x00020000);
        planEnd_ = 0L;
        onChanged();
        return this;
      }

      private long queueWaitEnd_ ;
      /**
       * <code>optional int64 queueWaitEnd = 19;</code>
       * @return Whether the queueWaitEnd field is set.
       */
      @java.lang.Override
      public boolean hasQueueWaitEnd() {
        return ((bitField0_ & 0x00040000) != 0);
      }
      /**
       * <code>optional int64 queueWaitEnd = 19;</code>
       * @return The queueWaitEnd.
       */
      @java.lang.Override
      public long getQueueWaitEnd() {
        return queueWaitEnd_;
      }
      /**
       * <code>optional int64 queueWaitEnd = 19;</code>
       * @param value The queueWaitEnd to set.
       * @return This builder for chaining.
       */
      public Builder setQueueWaitEnd(long value) {
        bitField0_ |= 0x00040000;
        queueWaitEnd_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 queueWaitEnd = 19;</code>
       * @return This builder for chaining.
       */
      public Builder clearQueueWaitEnd() {
        bitField0_ = (bitField0_ & ~0x00040000);
        queueWaitEnd_ = 0L;
        onChanged();
        return this;
      }

      private double totalCost_ ;
      /**
       * <code>optional double total_cost = 20;</code>
       * @return Whether the totalCost field is set.
       */
      @java.lang.Override
      public boolean hasTotalCost() {
        return ((bitField0_ & 0x00080000) != 0);
      }
      /**
       * <code>optional double total_cost = 20;</code>
       * @return The totalCost.
       */
      @java.lang.Override
      public double getTotalCost() {
        return totalCost_;
      }
      /**
       * <code>optional double total_cost = 20;</code>
       * @param value The totalCost to set.
       * @return This builder for chaining.
       */
      public Builder setTotalCost(double value) {
        bitField0_ |= 0x00080000;
        totalCost_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional double total_cost = 20;</code>
       * @return This builder for chaining.
       */
      public Builder clearTotalCost() {
        bitField0_ = (bitField0_ & ~0x00080000);
        totalCost_ = 0D;
        onChanged();
        return this;
      }

      private java.lang.Object queueName_ = "-";
      /**
       * <code>optional string queue_name = 21 [default = "-"];</code>
       * @return Whether the queueName field is set.
       */
      public boolean hasQueueName() {
        return ((bitField0_ & 0x00100000) != 0);
      }
      /**
       * <code>optional string queue_name = 21 [default = "-"];</code>
       * @return The queueName.
       */
      public java.lang.String getQueueName() {
        java.lang.Object ref = queueName_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            queueName_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string queue_name = 21 [default = "-"];</code>
       * @return The bytes for queueName.
       */
      public com.google.protobuf.ByteString
          getQueueNameBytes() {
        java.lang.Object ref = queueName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          queueName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string queue_name = 21 [default = "-"];</code>
       * @param value The queueName to set.
       * @return This builder for chaining.
       */
      public Builder setQueueName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00100000;
        queueName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string queue_name = 21 [default = "-"];</code>
       * @return This builder for chaining.
       */
      public Builder clearQueueName() {
        bitField0_ = (bitField0_ & ~0x00100000);
        queueName_ = getDefaultInstance().getQueueName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string queue_name = 21 [default = "-"];</code>
       * @param value The bytes for queueName to set.
       * @return This builder for chaining.
       */
      public Builder setQueueNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00100000;
        queueName_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object queryId_ = "";
      /**
       * <code>optional string queryId = 22;</code>
       * @return Whether the queryId field is set.
       */
      public boolean hasQueryId() {
        return ((bitField0_ & 0x00200000) != 0);
      }
      /**
       * <code>optional string queryId = 22;</code>
       * @return The queryId.
       */
      public java.lang.String getQueryId() {
        java.lang.Object ref = queryId_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            queryId_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string queryId = 22;</code>
       * @return The bytes for queryId.
       */
      public com.google.protobuf.ByteString
          getQueryIdBytes() {
        java.lang.Object ref = queryId_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          queryId_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string queryId = 22;</code>
       * @param value The queryId to set.
       * @return This builder for chaining.
       */
      public Builder setQueryId(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00200000;
        queryId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string queryId = 22;</code>
       * @return This builder for chaining.
       */
      public Builder clearQueryId() {
        bitField0_ = (bitField0_ & ~0x00200000);
        queryId_ = getDefaultInstance().getQueryId();
        onChanged();
        return this;
      }
      /**
       * <code>optional string queryId = 22;</code>
       * @param value The bytes for queryId to set.
       * @return This builder for chaining.
       */
      public Builder setQueryIdBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00200000;
        queryId_ = value;
        onChanged();
        return this;
      }

      private int autoLimit_ ;
      /**
       * <code>optional int32 autoLimit = 23;</code>
       * @return Whether the autoLimit field is set.
       */
      @java.lang.Override
      public boolean hasAutoLimit() {
        return ((bitField0_ & 0x00400000) != 0);
      }
      /**
       * <code>optional int32 autoLimit = 23;</code>
       * @return The autoLimit.
       */
      @java.lang.Override
      public int getAutoLimit() {
        return autoLimit_;
      }
      /**
       * <code>optional int32 autoLimit = 23;</code>
       * @param value The autoLimit to set.
       * @return This builder for chaining.
       */
      public Builder setAutoLimit(int value) {
        bitField0_ |= 0x00400000;
        autoLimit_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 autoLimit = 23;</code>
       * @return This builder for chaining.
       */
      public Builder clearAutoLimit() {
        bitField0_ = (bitField0_ & ~0x00400000);
        autoLimit_ = 0;
        onChanged();
        return this;
      }

      private com.google.protobuf.LazyStringList scannedPlugins_ = com.google.protobuf.LazyStringArrayList.EMPTY;
      private void ensureScannedPluginsIsMutable() {
        if (!((bitField0_ & 0x00800000) != 0)) {
          scannedPlugins_ = new com.google.protobuf.LazyStringArrayList(scannedPlugins_);
          bitField0_ |= 0x00800000;
         }
      }
      /**
       * <code>repeated string scanned_plugins = 24;</code>
       * @return A list containing the scannedPlugins.
       */
      public com.google.protobuf.ProtocolStringList
          getScannedPluginsList() {
        return scannedPlugins_.getUnmodifiableView();
      }
      /**
       * <code>repeated string scanned_plugins = 24;</code>
       * @return The count of scannedPlugins.
       */
      public int getScannedPluginsCount() {
        return scannedPlugins_.size();
      }
      /**
       * <code>repeated string scanned_plugins = 24;</code>
       * @param index The index of the element to return.
       * @return The scannedPlugins at the given index.
       */
      public java.lang.String getScannedPlugins(int index) {
        return scannedPlugins_.get(index);
      }
      /**
       * <code>repeated string scanned_plugins = 24;</code>
       * @param index The index of the value to return.
       * @return The bytes of the scannedPlugins at the given index.
       */
      public com.google.protobuf.ByteString
          getScannedPluginsBytes(int index) {
        return scannedPlugins_.getByteString(index);
      }
      /**
       * <code>repeated string scanned_plugins = 24;</code>
       * @param index The index to set the value at.
       * @param value The scannedPlugins to set.
       * @return This builder for chaining.
       */
      public Builder setScannedPlugins(
          int index, java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureScannedPluginsIsMutable();
        scannedPlugins_.set(index, value);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string scanned_plugins = 24;</code>
       * @param value The scannedPlugins to add.
       * @return This builder for chaining.
       */
      public Builder addScannedPlugins(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureScannedPluginsIsMutable();
        scannedPlugins_.add(value);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string scanned_plugins = 24;</code>
       * @param values The scannedPlugins to add.
       * @return This builder for chaining.
       */
      public Builder addAllScannedPlugins(
          java.lang.Iterable<java.lang.String> values) {
        ensureScannedPluginsIsMutable();
        com.google.protobuf.AbstractMessageLite.Builder.addAll(
            values, scannedPlugins_);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string scanned_plugins = 24;</code>
       * @return This builder for chaining.
       */
      public Builder clearScannedPlugins() {
        scannedPlugins_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        bitField0_ = (bitField0_ & ~0x00800000);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string scanned_plugins = 24;</code>
       * @param value The bytes of the scannedPlugins to add.
       * @return This builder for chaining.
       */
      public Builder addScannedPluginsBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureScannedPluginsIsMutable();
        scannedPlugins_.add(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:exec.shared.QueryProfile)
    }

    // @@protoc_insertion_point(class_scope:exec.shared.QueryProfile)
    private static final org.apache.drill.exec.proto.UserBitShared.QueryProfile DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserBitShared.QueryProfile();
    }

    public static org.apache.drill.exec.proto.UserBitShared.QueryProfile getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<QueryProfile>
        PARSER = new com.google.protobuf.AbstractParser<QueryProfile>() {
      @java.lang.Override
      public QueryProfile parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

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

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

    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.QueryProfile getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface MajorFragmentProfileOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.shared.MajorFragmentProfile)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional int32 major_fragment_id = 1;</code>
     * @return Whether the majorFragmentId field is set.
     */
    boolean hasMajorFragmentId();
    /**
     * <code>optional int32 major_fragment_id = 1;</code>
     * @return The majorFragmentId.
     */
    int getMajorFragmentId();

    /**
     * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
     */
    java.util.List<org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile> 
        getMinorFragmentProfileList();
    /**
     * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile getMinorFragmentProfile(int index);
    /**
     * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
     */
    int getMinorFragmentProfileCount();
    /**
     * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
     */
    java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfileOrBuilder> 
        getMinorFragmentProfileOrBuilderList();
    /**
     * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfileOrBuilder getMinorFragmentProfileOrBuilder(
        int index);
  }
  /**
   * Protobuf type {@code exec.shared.MajorFragmentProfile}
   */
  public static final class MajorFragmentProfile extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.MajorFragmentProfile)
      MajorFragmentProfileOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use MajorFragmentProfile.newBuilder() to construct.
    private MajorFragmentProfile(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private MajorFragmentProfile() {
      minorFragmentProfile_ = java.util.Collections.emptyList();
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new MajorFragmentProfile();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_MajorFragmentProfile_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_MajorFragmentProfile_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile.class, org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile.Builder.class);
    }

    private int bitField0_;
    public static final int MAJOR_FRAGMENT_ID_FIELD_NUMBER = 1;
    private int majorFragmentId_;
    /**
     * <code>optional int32 major_fragment_id = 1;</code>
     * @return Whether the majorFragmentId field is set.
     */
    @java.lang.Override
    public boolean hasMajorFragmentId() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional int32 major_fragment_id = 1;</code>
     * @return The majorFragmentId.
     */
    @java.lang.Override
    public int getMajorFragmentId() {
      return majorFragmentId_;
    }

    public static final int MINOR_FRAGMENT_PROFILE_FIELD_NUMBER = 2;
    private java.util.List<org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile> minorFragmentProfile_;
    /**
     * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile> getMinorFragmentProfileList() {
      return minorFragmentProfile_;
    }
    /**
     * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
     */
    @java.lang.Override
    public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfileOrBuilder> 
        getMinorFragmentProfileOrBuilderList() {
      return minorFragmentProfile_;
    }
    /**
     * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
     */
    @java.lang.Override
    public int getMinorFragmentProfileCount() {
      return minorFragmentProfile_.size();
    }
    /**
     * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile getMinorFragmentProfile(int index) {
      return minorFragmentProfile_.get(index);
    }
    /**
     * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfileOrBuilder getMinorFragmentProfileOrBuilder(
        int index) {
      return minorFragmentProfile_.get(index);
    }

    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 (((bitField0_ & 0x00000001) != 0)) {
        output.writeInt32(1, majorFragmentId_);
      }
      for (int i = 0; i < minorFragmentProfile_.size(); i++) {
        output.writeMessage(2, minorFragmentProfile_.get(i));
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(1, majorFragmentId_);
      }
      for (int i = 0; i < minorFragmentProfile_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, minorFragmentProfile_.get(i));
      }
      size += getUnknownFields().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.drill.exec.proto.UserBitShared.MajorFragmentProfile)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile other = (org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile) obj;

      if (hasMajorFragmentId() != other.hasMajorFragmentId()) return false;
      if (hasMajorFragmentId()) {
        if (getMajorFragmentId()
            != other.getMajorFragmentId()) return false;
      }
      if (!getMinorFragmentProfileList()
          .equals(other.getMinorFragmentProfileList())) return false;
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasMajorFragmentId()) {
        hash = (37 * hash) + MAJOR_FRAGMENT_ID_FIELD_NUMBER;
        hash = (53 * hash) + getMajorFragmentId();
      }
      if (getMinorFragmentProfileCount() > 0) {
        hash = (37 * hash) + MINOR_FRAGMENT_PROFILE_FIELD_NUMBER;
        hash = (53 * hash) + getMinorFragmentProfileList().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile 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.drill.exec.proto.UserBitShared.MajorFragmentProfile parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile 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.drill.exec.proto.UserBitShared.MajorFragmentProfile parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile 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.drill.exec.proto.UserBitShared.MajorFragmentProfile parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile 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.drill.exec.proto.UserBitShared.MajorFragmentProfile 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 exec.shared.MajorFragmentProfile}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.shared.MajorFragmentProfile)
        org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfileOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_MajorFragmentProfile_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_MajorFragmentProfile_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile.class, org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        majorFragmentId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        if (minorFragmentProfileBuilder_ == null) {
          minorFragmentProfile_ = java.util.Collections.emptyList();
        } else {
          minorFragmentProfile_ = null;
          minorFragmentProfileBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_MajorFragmentProfile_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile build() {
        org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile buildPartial() {
        org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile result = new org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.majorFragmentId_ = majorFragmentId_;
          to_bitField0_ |= 0x00000001;
        }
        if (minorFragmentProfileBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0)) {
            minorFragmentProfile_ = java.util.Collections.unmodifiableList(minorFragmentProfile_);
            bitField0_ = (bitField0_ & ~0x00000002);
          }
          result.minorFragmentProfile_ = minorFragmentProfile_;
        } else {
          result.minorFragmentProfile_ = minorFragmentProfileBuilder_.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.drill.exec.proto.UserBitShared.MajorFragmentProfile) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile.getDefaultInstance()) return this;
        if (other.hasMajorFragmentId()) {
          setMajorFragmentId(other.getMajorFragmentId());
        }
        if (minorFragmentProfileBuilder_ == null) {
          if (!other.minorFragmentProfile_.isEmpty()) {
            if (minorFragmentProfile_.isEmpty()) {
              minorFragmentProfile_ = other.minorFragmentProfile_;
              bitField0_ = (bitField0_ & ~0x00000002);
            } else {
              ensureMinorFragmentProfileIsMutable();
              minorFragmentProfile_.addAll(other.minorFragmentProfile_);
            }
            onChanged();
          }
        } else {
          if (!other.minorFragmentProfile_.isEmpty()) {
            if (minorFragmentProfileBuilder_.isEmpty()) {
              minorFragmentProfileBuilder_.dispose();
              minorFragmentProfileBuilder_ = null;
              minorFragmentProfile_ = other.minorFragmentProfile_;
              bitField0_ = (bitField0_ & ~0x00000002);
              minorFragmentProfileBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getMinorFragmentProfileFieldBuilder() : null;
            } else {
              minorFragmentProfileBuilder_.addAllMessages(other.minorFragmentProfile_);
            }
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        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 {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                majorFragmentId_ = input.readInt32();
                bitField0_ |= 0x00000001;
                break;
              } // case 8
              case 18: {
                org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile m =
                    input.readMessage(
                        org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.PARSER,
                        extensionRegistry);
                if (minorFragmentProfileBuilder_ == null) {
                  ensureMinorFragmentProfileIsMutable();
                  minorFragmentProfile_.add(m);
                } else {
                  minorFragmentProfileBuilder_.addMessage(m);
                }
                break;
              } // case 18
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private int majorFragmentId_ ;
      /**
       * <code>optional int32 major_fragment_id = 1;</code>
       * @return Whether the majorFragmentId field is set.
       */
      @java.lang.Override
      public boolean hasMajorFragmentId() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional int32 major_fragment_id = 1;</code>
       * @return The majorFragmentId.
       */
      @java.lang.Override
      public int getMajorFragmentId() {
        return majorFragmentId_;
      }
      /**
       * <code>optional int32 major_fragment_id = 1;</code>
       * @param value The majorFragmentId to set.
       * @return This builder for chaining.
       */
      public Builder setMajorFragmentId(int value) {
        bitField0_ |= 0x00000001;
        majorFragmentId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 major_fragment_id = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearMajorFragmentId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        majorFragmentId_ = 0;
        onChanged();
        return this;
      }

      private java.util.List<org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile> minorFragmentProfile_ =
        java.util.Collections.emptyList();
      private void ensureMinorFragmentProfileIsMutable() {
        if (!((bitField0_ & 0x00000002) != 0)) {
          minorFragmentProfile_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile>(minorFragmentProfile_);
          bitField0_ |= 0x00000002;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile, org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.Builder, org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfileOrBuilder> minorFragmentProfileBuilder_;

      /**
       * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile> getMinorFragmentProfileList() {
        if (minorFragmentProfileBuilder_ == null) {
          return java.util.Collections.unmodifiableList(minorFragmentProfile_);
        } else {
          return minorFragmentProfileBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
       */
      public int getMinorFragmentProfileCount() {
        if (minorFragmentProfileBuilder_ == null) {
          return minorFragmentProfile_.size();
        } else {
          return minorFragmentProfileBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile getMinorFragmentProfile(int index) {
        if (minorFragmentProfileBuilder_ == null) {
          return minorFragmentProfile_.get(index);
        } else {
          return minorFragmentProfileBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
       */
      public Builder setMinorFragmentProfile(
          int index, org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile value) {
        if (minorFragmentProfileBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureMinorFragmentProfileIsMutable();
          minorFragmentProfile_.set(index, value);
          onChanged();
        } else {
          minorFragmentProfileBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
       */
      public Builder setMinorFragmentProfile(
          int index, org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.Builder builderForValue) {
        if (minorFragmentProfileBuilder_ == null) {
          ensureMinorFragmentProfileIsMutable();
          minorFragmentProfile_.set(index, builderForValue.build());
          onChanged();
        } else {
          minorFragmentProfileBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
       */
      public Builder addMinorFragmentProfile(org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile value) {
        if (minorFragmentProfileBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureMinorFragmentProfileIsMutable();
          minorFragmentProfile_.add(value);
          onChanged();
        } else {
          minorFragmentProfileBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
       */
      public Builder addMinorFragmentProfile(
          int index, org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile value) {
        if (minorFragmentProfileBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureMinorFragmentProfileIsMutable();
          minorFragmentProfile_.add(index, value);
          onChanged();
        } else {
          minorFragmentProfileBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
       */
      public Builder addMinorFragmentProfile(
          org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.Builder builderForValue) {
        if (minorFragmentProfileBuilder_ == null) {
          ensureMinorFragmentProfileIsMutable();
          minorFragmentProfile_.add(builderForValue.build());
          onChanged();
        } else {
          minorFragmentProfileBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
       */
      public Builder addMinorFragmentProfile(
          int index, org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.Builder builderForValue) {
        if (minorFragmentProfileBuilder_ == null) {
          ensureMinorFragmentProfileIsMutable();
          minorFragmentProfile_.add(index, builderForValue.build());
          onChanged();
        } else {
          minorFragmentProfileBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
       */
      public Builder addAllMinorFragmentProfile(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile> values) {
        if (minorFragmentProfileBuilder_ == null) {
          ensureMinorFragmentProfileIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, minorFragmentProfile_);
          onChanged();
        } else {
          minorFragmentProfileBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
       */
      public Builder clearMinorFragmentProfile() {
        if (minorFragmentProfileBuilder_ == null) {
          minorFragmentProfile_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000002);
          onChanged();
        } else {
          minorFragmentProfileBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
       */
      public Builder removeMinorFragmentProfile(int index) {
        if (minorFragmentProfileBuilder_ == null) {
          ensureMinorFragmentProfileIsMutable();
          minorFragmentProfile_.remove(index);
          onChanged();
        } else {
          minorFragmentProfileBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.Builder getMinorFragmentProfileBuilder(
          int index) {
        return getMinorFragmentProfileFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfileOrBuilder getMinorFragmentProfileOrBuilder(
          int index) {
        if (minorFragmentProfileBuilder_ == null) {
          return minorFragmentProfile_.get(index);  } else {
          return minorFragmentProfileBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
       */
      public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfileOrBuilder> 
           getMinorFragmentProfileOrBuilderList() {
        if (minorFragmentProfileBuilder_ != null) {
          return minorFragmentProfileBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(minorFragmentProfile_);
        }
      }
      /**
       * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.Builder addMinorFragmentProfileBuilder() {
        return getMinorFragmentProfileFieldBuilder().addBuilder(
            org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.Builder addMinorFragmentProfileBuilder(
          int index) {
        return getMinorFragmentProfileFieldBuilder().addBuilder(
            index, org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.Builder> 
           getMinorFragmentProfileBuilderList() {
        return getMinorFragmentProfileFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile, org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.Builder, org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfileOrBuilder> 
          getMinorFragmentProfileFieldBuilder() {
        if (minorFragmentProfileBuilder_ == null) {
          minorFragmentProfileBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile, org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.Builder, org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfileOrBuilder>(
                  minorFragmentProfile_,
                  ((bitField0_ & 0x00000002) != 0),
                  getParentForChildren(),
                  isClean());
          minorFragmentProfile_ = null;
        }
        return minorFragmentProfileBuilder_;
      }
      @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:exec.shared.MajorFragmentProfile)
    }

    // @@protoc_insertion_point(class_scope:exec.shared.MajorFragmentProfile)
    private static final org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile();
    }

    public static org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<MajorFragmentProfile>
        PARSER = new com.google.protobuf.AbstractParser<MajorFragmentProfile>() {
      @java.lang.Override
      public MajorFragmentProfile parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

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

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

    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface MinorFragmentProfileOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.shared.MinorFragmentProfile)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional .exec.shared.FragmentState state = 1;</code>
     * @return Whether the state field is set.
     */
    boolean hasState();
    /**
     * <code>optional .exec.shared.FragmentState state = 1;</code>
     * @return The state.
     */
    org.apache.drill.exec.proto.UserBitShared.FragmentState getState();

    /**
     * <code>optional .exec.shared.DrillPBError error = 2;</code>
     * @return Whether the error field is set.
     */
    boolean hasError();
    /**
     * <code>optional .exec.shared.DrillPBError error = 2;</code>
     * @return The error.
     */
    org.apache.drill.exec.proto.UserBitShared.DrillPBError getError();
    /**
     * <code>optional .exec.shared.DrillPBError error = 2;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder();

    /**
     * <code>optional int32 minor_fragment_id = 3;</code>
     * @return Whether the minorFragmentId field is set.
     */
    boolean hasMinorFragmentId();
    /**
     * <code>optional int32 minor_fragment_id = 3;</code>
     * @return The minorFragmentId.
     */
    int getMinorFragmentId();

    /**
     * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
     */
    java.util.List<org.apache.drill.exec.proto.UserBitShared.OperatorProfile> 
        getOperatorProfileList();
    /**
     * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.OperatorProfile getOperatorProfile(int index);
    /**
     * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
     */
    int getOperatorProfileCount();
    /**
     * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
     */
    java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.OperatorProfileOrBuilder> 
        getOperatorProfileOrBuilderList();
    /**
     * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.OperatorProfileOrBuilder getOperatorProfileOrBuilder(
        int index);

    /**
     * <code>optional int64 start_time = 5;</code>
     * @return Whether the startTime field is set.
     */
    boolean hasStartTime();
    /**
     * <code>optional int64 start_time = 5;</code>
     * @return The startTime.
     */
    long getStartTime();

    /**
     * <code>optional int64 end_time = 6;</code>
     * @return Whether the endTime field is set.
     */
    boolean hasEndTime();
    /**
     * <code>optional int64 end_time = 6;</code>
     * @return The endTime.
     */
    long getEndTime();

    /**
     * <code>optional int64 memory_used = 7;</code>
     * @return Whether the memoryUsed field is set.
     */
    boolean hasMemoryUsed();
    /**
     * <code>optional int64 memory_used = 7;</code>
     * @return The memoryUsed.
     */
    long getMemoryUsed();

    /**
     * <code>optional int64 max_memory_used = 8;</code>
     * @return Whether the maxMemoryUsed field is set.
     */
    boolean hasMaxMemoryUsed();
    /**
     * <code>optional int64 max_memory_used = 8;</code>
     * @return The maxMemoryUsed.
     */
    long getMaxMemoryUsed();

    /**
     * <code>optional .exec.DrillbitEndpoint endpoint = 9;</code>
     * @return Whether the endpoint field is set.
     */
    boolean hasEndpoint();
    /**
     * <code>optional .exec.DrillbitEndpoint endpoint = 9;</code>
     * @return The endpoint.
     */
    org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint getEndpoint();
    /**
     * <code>optional .exec.DrillbitEndpoint endpoint = 9;</code>
     */
    org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder getEndpointOrBuilder();

    /**
     * <code>optional int64 last_update = 10;</code>
     * @return Whether the lastUpdate field is set.
     */
    boolean hasLastUpdate();
    /**
     * <code>optional int64 last_update = 10;</code>
     * @return The lastUpdate.
     */
    long getLastUpdate();

    /**
     * <code>optional int64 last_progress = 11;</code>
     * @return Whether the lastProgress field is set.
     */
    boolean hasLastProgress();
    /**
     * <code>optional int64 last_progress = 11;</code>
     * @return The lastProgress.
     */
    long getLastProgress();
  }
  /**
   * Protobuf type {@code exec.shared.MinorFragmentProfile}
   */
  public static final class MinorFragmentProfile extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.MinorFragmentProfile)
      MinorFragmentProfileOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use MinorFragmentProfile.newBuilder() to construct.
    private MinorFragmentProfile(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private MinorFragmentProfile() {
      state_ = 0;
      operatorProfile_ = java.util.Collections.emptyList();
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new MinorFragmentProfile();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_MinorFragmentProfile_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_MinorFragmentProfile_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.class, org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.Builder.class);
    }

    private int bitField0_;
    public static final int STATE_FIELD_NUMBER = 1;
    private int state_;
    /**
     * <code>optional .exec.shared.FragmentState state = 1;</code>
     * @return Whether the state field is set.
     */
    @java.lang.Override public boolean hasState() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional .exec.shared.FragmentState state = 1;</code>
     * @return The state.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserBitShared.FragmentState getState() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserBitShared.FragmentState result = org.apache.drill.exec.proto.UserBitShared.FragmentState.valueOf(state_);
      return result == null ? org.apache.drill.exec.proto.UserBitShared.FragmentState.SENDING : result;
    }

    public static final int ERROR_FIELD_NUMBER = 2;
    private org.apache.drill.exec.proto.UserBitShared.DrillPBError error_;
    /**
     * <code>optional .exec.shared.DrillPBError error = 2;</code>
     * @return Whether the error field is set.
     */
    @java.lang.Override
    public boolean hasError() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .exec.shared.DrillPBError error = 2;</code>
     * @return The error.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.DrillPBError getError() {
      return error_ == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
    }
    /**
     * <code>optional .exec.shared.DrillPBError error = 2;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder() {
      return error_ == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
    }

    public static final int MINOR_FRAGMENT_ID_FIELD_NUMBER = 3;
    private int minorFragmentId_;
    /**
     * <code>optional int32 minor_fragment_id = 3;</code>
     * @return Whether the minorFragmentId field is set.
     */
    @java.lang.Override
    public boolean hasMinorFragmentId() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional int32 minor_fragment_id = 3;</code>
     * @return The minorFragmentId.
     */
    @java.lang.Override
    public int getMinorFragmentId() {
      return minorFragmentId_;
    }

    public static final int OPERATOR_PROFILE_FIELD_NUMBER = 4;
    private java.util.List<org.apache.drill.exec.proto.UserBitShared.OperatorProfile> operatorProfile_;
    /**
     * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.UserBitShared.OperatorProfile> getOperatorProfileList() {
      return operatorProfile_;
    }
    /**
     * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
     */
    @java.lang.Override
    public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.OperatorProfileOrBuilder> 
        getOperatorProfileOrBuilderList() {
      return operatorProfile_;
    }
    /**
     * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
     */
    @java.lang.Override
    public int getOperatorProfileCount() {
      return operatorProfile_.size();
    }
    /**
     * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.OperatorProfile getOperatorProfile(int index) {
      return operatorProfile_.get(index);
    }
    /**
     * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.OperatorProfileOrBuilder getOperatorProfileOrBuilder(
        int index) {
      return operatorProfile_.get(index);
    }

    public static final int START_TIME_FIELD_NUMBER = 5;
    private long startTime_;
    /**
     * <code>optional int64 start_time = 5;</code>
     * @return Whether the startTime field is set.
     */
    @java.lang.Override
    public boolean hasStartTime() {
      return ((bitField0_ & 0x00000008) != 0);
    }
    /**
     * <code>optional int64 start_time = 5;</code>
     * @return The startTime.
     */
    @java.lang.Override
    public long getStartTime() {
      return startTime_;
    }

    public static final int END_TIME_FIELD_NUMBER = 6;
    private long endTime_;
    /**
     * <code>optional int64 end_time = 6;</code>
     * @return Whether the endTime field is set.
     */
    @java.lang.Override
    public boolean hasEndTime() {
      return ((bitField0_ & 0x00000010) != 0);
    }
    /**
     * <code>optional int64 end_time = 6;</code>
     * @return The endTime.
     */
    @java.lang.Override
    public long getEndTime() {
      return endTime_;
    }

    public static final int MEMORY_USED_FIELD_NUMBER = 7;
    private long memoryUsed_;
    /**
     * <code>optional int64 memory_used = 7;</code>
     * @return Whether the memoryUsed field is set.
     */
    @java.lang.Override
    public boolean hasMemoryUsed() {
      return ((bitField0_ & 0x00000020) != 0);
    }
    /**
     * <code>optional int64 memory_used = 7;</code>
     * @return The memoryUsed.
     */
    @java.lang.Override
    public long getMemoryUsed() {
      return memoryUsed_;
    }

    public static final int MAX_MEMORY_USED_FIELD_NUMBER = 8;
    private long maxMemoryUsed_;
    /**
     * <code>optional int64 max_memory_used = 8;</code>
     * @return Whether the maxMemoryUsed field is set.
     */
    @java.lang.Override
    public boolean hasMaxMemoryUsed() {
      return ((bitField0_ & 0x00000040) != 0);
    }
    /**
     * <code>optional int64 max_memory_used = 8;</code>
     * @return The maxMemoryUsed.
     */
    @java.lang.Override
    public long getMaxMemoryUsed() {
      return maxMemoryUsed_;
    }

    public static final int ENDPOINT_FIELD_NUMBER = 9;
    private org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint endpoint_;
    /**
     * <code>optional .exec.DrillbitEndpoint endpoint = 9;</code>
     * @return Whether the endpoint field is set.
     */
    @java.lang.Override
    public boolean hasEndpoint() {
      return ((bitField0_ & 0x00000080) != 0);
    }
    /**
     * <code>optional .exec.DrillbitEndpoint endpoint = 9;</code>
     * @return The endpoint.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint getEndpoint() {
      return endpoint_ == null ? org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance() : endpoint_;
    }
    /**
     * <code>optional .exec.DrillbitEndpoint endpoint = 9;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder getEndpointOrBuilder() {
      return endpoint_ == null ? org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance() : endpoint_;
    }

    public static final int LAST_UPDATE_FIELD_NUMBER = 10;
    private long lastUpdate_;
    /**
     * <code>optional int64 last_update = 10;</code>
     * @return Whether the lastUpdate field is set.
     */
    @java.lang.Override
    public boolean hasLastUpdate() {
      return ((bitField0_ & 0x00000100) != 0);
    }
    /**
     * <code>optional int64 last_update = 10;</code>
     * @return The lastUpdate.
     */
    @java.lang.Override
    public long getLastUpdate() {
      return lastUpdate_;
    }

    public static final int LAST_PROGRESS_FIELD_NUMBER = 11;
    private long lastProgress_;
    /**
     * <code>optional int64 last_progress = 11;</code>
     * @return Whether the lastProgress field is set.
     */
    @java.lang.Override
    public boolean hasLastProgress() {
      return ((bitField0_ & 0x00000200) != 0);
    }
    /**
     * <code>optional int64 last_progress = 11;</code>
     * @return The lastProgress.
     */
    @java.lang.Override
    public long getLastProgress() {
      return lastProgress_;
    }

    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 (((bitField0_ & 0x00000001) != 0)) {
        output.writeEnum(1, state_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeMessage(2, getError());
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeInt32(3, minorFragmentId_);
      }
      for (int i = 0; i < operatorProfile_.size(); i++) {
        output.writeMessage(4, operatorProfile_.get(i));
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        output.writeInt64(5, startTime_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        output.writeInt64(6, endTime_);
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        output.writeInt64(7, memoryUsed_);
      }
      if (((bitField0_ & 0x00000040) != 0)) {
        output.writeInt64(8, maxMemoryUsed_);
      }
      if (((bitField0_ & 0x00000080) != 0)) {
        output.writeMessage(9, getEndpoint());
      }
      if (((bitField0_ & 0x00000100) != 0)) {
        output.writeInt64(10, lastUpdate_);
      }
      if (((bitField0_ & 0x00000200) != 0)) {
        output.writeInt64(11, lastProgress_);
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(1, state_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, getError());
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(3, minorFragmentId_);
      }
      for (int i = 0; i < operatorProfile_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(4, operatorProfile_.get(i));
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(5, startTime_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(6, endTime_);
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(7, memoryUsed_);
      }
      if (((bitField0_ & 0x00000040) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(8, maxMemoryUsed_);
      }
      if (((bitField0_ & 0x00000080) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(9, getEndpoint());
      }
      if (((bitField0_ & 0x00000100) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(10, lastUpdate_);
      }
      if (((bitField0_ & 0x00000200) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(11, lastProgress_);
      }
      size += getUnknownFields().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.drill.exec.proto.UserBitShared.MinorFragmentProfile)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile other = (org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile) obj;

      if (hasState() != other.hasState()) return false;
      if (hasState()) {
        if (state_ != other.state_) return false;
      }
      if (hasError() != other.hasError()) return false;
      if (hasError()) {
        if (!getError()
            .equals(other.getError())) return false;
      }
      if (hasMinorFragmentId() != other.hasMinorFragmentId()) return false;
      if (hasMinorFragmentId()) {
        if (getMinorFragmentId()
            != other.getMinorFragmentId()) return false;
      }
      if (!getOperatorProfileList()
          .equals(other.getOperatorProfileList())) return false;
      if (hasStartTime() != other.hasStartTime()) return false;
      if (hasStartTime()) {
        if (getStartTime()
            != other.getStartTime()) return false;
      }
      if (hasEndTime() != other.hasEndTime()) return false;
      if (hasEndTime()) {
        if (getEndTime()
            != other.getEndTime()) return false;
      }
      if (hasMemoryUsed() != other.hasMemoryUsed()) return false;
      if (hasMemoryUsed()) {
        if (getMemoryUsed()
            != other.getMemoryUsed()) return false;
      }
      if (hasMaxMemoryUsed() != other.hasMaxMemoryUsed()) return false;
      if (hasMaxMemoryUsed()) {
        if (getMaxMemoryUsed()
            != other.getMaxMemoryUsed()) return false;
      }
      if (hasEndpoint() != other.hasEndpoint()) return false;
      if (hasEndpoint()) {
        if (!getEndpoint()
            .equals(other.getEndpoint())) return false;
      }
      if (hasLastUpdate() != other.hasLastUpdate()) return false;
      if (hasLastUpdate()) {
        if (getLastUpdate()
            != other.getLastUpdate()) return false;
      }
      if (hasLastProgress() != other.hasLastProgress()) return false;
      if (hasLastProgress()) {
        if (getLastProgress()
            != other.getLastProgress()) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasState()) {
        hash = (37 * hash) + STATE_FIELD_NUMBER;
        hash = (53 * hash) + state_;
      }
      if (hasError()) {
        hash = (37 * hash) + ERROR_FIELD_NUMBER;
        hash = (53 * hash) + getError().hashCode();
      }
      if (hasMinorFragmentId()) {
        hash = (37 * hash) + MINOR_FRAGMENT_ID_FIELD_NUMBER;
        hash = (53 * hash) + getMinorFragmentId();
      }
      if (getOperatorProfileCount() > 0) {
        hash = (37 * hash) + OPERATOR_PROFILE_FIELD_NUMBER;
        hash = (53 * hash) + getOperatorProfileList().hashCode();
      }
      if (hasStartTime()) {
        hash = (37 * hash) + START_TIME_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getStartTime());
      }
      if (hasEndTime()) {
        hash = (37 * hash) + END_TIME_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getEndTime());
      }
      if (hasMemoryUsed()) {
        hash = (37 * hash) + MEMORY_USED_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getMemoryUsed());
      }
      if (hasMaxMemoryUsed()) {
        hash = (37 * hash) + MAX_MEMORY_USED_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getMaxMemoryUsed());
      }
      if (hasEndpoint()) {
        hash = (37 * hash) + ENDPOINT_FIELD_NUMBER;
        hash = (53 * hash) + getEndpoint().hashCode();
      }
      if (hasLastUpdate()) {
        hash = (37 * hash) + LAST_UPDATE_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getLastUpdate());
      }
      if (hasLastProgress()) {
        hash = (37 * hash) + LAST_PROGRESS_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getLastProgress());
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile 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.drill.exec.proto.UserBitShared.MinorFragmentProfile parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile 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.drill.exec.proto.UserBitShared.MinorFragmentProfile parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile 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.drill.exec.proto.UserBitShared.MinorFragmentProfile parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile 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.drill.exec.proto.UserBitShared.MinorFragmentProfile 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 exec.shared.MinorFragmentProfile}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.shared.MinorFragmentProfile)
        org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfileOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_MinorFragmentProfile_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_MinorFragmentProfile_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.class, org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getErrorFieldBuilder();
          getOperatorProfileFieldBuilder();
          getEndpointFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        state_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        if (errorBuilder_ == null) {
          error_ = null;
        } else {
          errorBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        minorFragmentId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000004);
        if (operatorProfileBuilder_ == null) {
          operatorProfile_ = java.util.Collections.emptyList();
        } else {
          operatorProfile_ = null;
          operatorProfileBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        startTime_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000010);
        endTime_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000020);
        memoryUsed_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000040);
        maxMemoryUsed_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000080);
        if (endpointBuilder_ == null) {
          endpoint_ = null;
        } else {
          endpointBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000100);
        lastUpdate_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000200);
        lastProgress_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000400);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_MinorFragmentProfile_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile build() {
        org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile buildPartial() {
        org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile result = new org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.state_ = state_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          if (errorBuilder_ == null) {
            result.error_ = error_;
          } else {
            result.error_ = errorBuilder_.build();
          }
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.minorFragmentId_ = minorFragmentId_;
          to_bitField0_ |= 0x00000004;
        }
        if (operatorProfileBuilder_ == null) {
          if (((bitField0_ & 0x00000008) != 0)) {
            operatorProfile_ = java.util.Collections.unmodifiableList(operatorProfile_);
            bitField0_ = (bitField0_ & ~0x00000008);
          }
          result.operatorProfile_ = operatorProfile_;
        } else {
          result.operatorProfile_ = operatorProfileBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000010) != 0)) {
          result.startTime_ = startTime_;
          to_bitField0_ |= 0x00000008;
        }
        if (((from_bitField0_ & 0x00000020) != 0)) {
          result.endTime_ = endTime_;
          to_bitField0_ |= 0x00000010;
        }
        if (((from_bitField0_ & 0x00000040) != 0)) {
          result.memoryUsed_ = memoryUsed_;
          to_bitField0_ |= 0x00000020;
        }
        if (((from_bitField0_ & 0x00000080) != 0)) {
          result.maxMemoryUsed_ = maxMemoryUsed_;
          to_bitField0_ |= 0x00000040;
        }
        if (((from_bitField0_ & 0x00000100) != 0)) {
          if (endpointBuilder_ == null) {
            result.endpoint_ = endpoint_;
          } else {
            result.endpoint_ = endpointBuilder_.build();
          }
          to_bitField0_ |= 0x00000080;
        }
        if (((from_bitField0_ & 0x00000200) != 0)) {
          result.lastUpdate_ = lastUpdate_;
          to_bitField0_ |= 0x00000100;
        }
        if (((from_bitField0_ & 0x00000400) != 0)) {
          result.lastProgress_ = lastProgress_;
          to_bitField0_ |= 0x00000200;
        }
        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.drill.exec.proto.UserBitShared.MinorFragmentProfile) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.getDefaultInstance()) return this;
        if (other.hasState()) {
          setState(other.getState());
        }
        if (other.hasError()) {
          mergeError(other.getError());
        }
        if (other.hasMinorFragmentId()) {
          setMinorFragmentId(other.getMinorFragmentId());
        }
        if (operatorProfileBuilder_ == null) {
          if (!other.operatorProfile_.isEmpty()) {
            if (operatorProfile_.isEmpty()) {
              operatorProfile_ = other.operatorProfile_;
              bitField0_ = (bitField0_ & ~0x00000008);
            } else {
              ensureOperatorProfileIsMutable();
              operatorProfile_.addAll(other.operatorProfile_);
            }
            onChanged();
          }
        } else {
          if (!other.operatorProfile_.isEmpty()) {
            if (operatorProfileBuilder_.isEmpty()) {
              operatorProfileBuilder_.dispose();
              operatorProfileBuilder_ = null;
              operatorProfile_ = other.operatorProfile_;
              bitField0_ = (bitField0_ & ~0x00000008);
              operatorProfileBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getOperatorProfileFieldBuilder() : null;
            } else {
              operatorProfileBuilder_.addAllMessages(other.operatorProfile_);
            }
          }
        }
        if (other.hasStartTime()) {
          setStartTime(other.getStartTime());
        }
        if (other.hasEndTime()) {
          setEndTime(other.getEndTime());
        }
        if (other.hasMemoryUsed()) {
          setMemoryUsed(other.getMemoryUsed());
        }
        if (other.hasMaxMemoryUsed()) {
          setMaxMemoryUsed(other.getMaxMemoryUsed());
        }
        if (other.hasEndpoint()) {
          mergeEndpoint(other.getEndpoint());
        }
        if (other.hasLastUpdate()) {
          setLastUpdate(other.getLastUpdate());
        }
        if (other.hasLastProgress()) {
          setLastProgress(other.getLastProgress());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        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 {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserBitShared.FragmentState tmpValue =
                    org.apache.drill.exec.proto.UserBitShared.FragmentState.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(1, tmpRaw);
                } else {
                  state_ = tmpRaw;
                  bitField0_ |= 0x00000001;
                }
                break;
              } // case 8
              case 18: {
                input.readMessage(
                    getErrorFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              case 24: {
                minorFragmentId_ = input.readInt32();
                bitField0_ |= 0x00000004;
                break;
              } // case 24
              case 34: {
                org.apache.drill.exec.proto.UserBitShared.OperatorProfile m =
                    input.readMessage(
                        org.apache.drill.exec.proto.UserBitShared.OperatorProfile.PARSER,
                        extensionRegistry);
                if (operatorProfileBuilder_ == null) {
                  ensureOperatorProfileIsMutable();
                  operatorProfile_.add(m);
                } else {
                  operatorProfileBuilder_.addMessage(m);
                }
                break;
              } // case 34
              case 40: {
                startTime_ = input.readInt64();
                bitField0_ |= 0x00000010;
                break;
              } // case 40
              case 48: {
                endTime_ = input.readInt64();
                bitField0_ |= 0x00000020;
                break;
              } // case 48
              case 56: {
                memoryUsed_ = input.readInt64();
                bitField0_ |= 0x00000040;
                break;
              } // case 56
              case 64: {
                maxMemoryUsed_ = input.readInt64();
                bitField0_ |= 0x00000080;
                break;
              } // case 64
              case 74: {
                input.readMessage(
                    getEndpointFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000100;
                break;
              } // case 74
              case 80: {
                lastUpdate_ = input.readInt64();
                bitField0_ |= 0x00000200;
                break;
              } // case 80
              case 88: {
                lastProgress_ = input.readInt64();
                bitField0_ |= 0x00000400;
                break;
              } // case 88
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private int state_ = 0;
      /**
       * <code>optional .exec.shared.FragmentState state = 1;</code>
       * @return Whether the state field is set.
       */
      @java.lang.Override public boolean hasState() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .exec.shared.FragmentState state = 1;</code>
       * @return The state.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.FragmentState getState() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserBitShared.FragmentState result = org.apache.drill.exec.proto.UserBitShared.FragmentState.valueOf(state_);
        return result == null ? org.apache.drill.exec.proto.UserBitShared.FragmentState.SENDING : result;
      }
      /**
       * <code>optional .exec.shared.FragmentState state = 1;</code>
       * @param value The state to set.
       * @return This builder for chaining.
       */
      public Builder setState(org.apache.drill.exec.proto.UserBitShared.FragmentState value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000001;
        state_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .exec.shared.FragmentState state = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearState() {
        bitField0_ = (bitField0_ & ~0x00000001);
        state_ = 0;
        onChanged();
        return this;
      }

      private org.apache.drill.exec.proto.UserBitShared.DrillPBError error_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder> errorBuilder_;
      /**
       * <code>optional .exec.shared.DrillPBError error = 2;</code>
       * @return Whether the error field is set.
       */
      public boolean hasError() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 2;</code>
       * @return The error.
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBError getError() {
        if (errorBuilder_ == null) {
          return error_ == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
        } else {
          return errorBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 2;</code>
       */
      public Builder setError(org.apache.drill.exec.proto.UserBitShared.DrillPBError value) {
        if (errorBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          error_ = value;
          onChanged();
        } else {
          errorBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 2;</code>
       */
      public Builder setError(
          org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder builderForValue) {
        if (errorBuilder_ == null) {
          error_ = builderForValue.build();
          onChanged();
        } else {
          errorBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 2;</code>
       */
      public Builder mergeError(org.apache.drill.exec.proto.UserBitShared.DrillPBError value) {
        if (errorBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0) &&
              error_ != null &&
              error_ != org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance()) {
            error_ =
              org.apache.drill.exec.proto.UserBitShared.DrillPBError.newBuilder(error_).mergeFrom(value).buildPartial();
          } else {
            error_ = value;
          }
          onChanged();
        } else {
          errorBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 2;</code>
       */
      public Builder clearError() {
        if (errorBuilder_ == null) {
          error_ = null;
          onChanged();
        } else {
          errorBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 2;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder getErrorBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getErrorFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 2;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder() {
        if (errorBuilder_ != null) {
          return errorBuilder_.getMessageOrBuilder();
        } else {
          return error_ == null ?
              org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
        }
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 2;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder> 
          getErrorFieldBuilder() {
        if (errorBuilder_ == null) {
          errorBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder>(
                  getError(),
                  getParentForChildren(),
                  isClean());
          error_ = null;
        }
        return errorBuilder_;
      }

      private int minorFragmentId_ ;
      /**
       * <code>optional int32 minor_fragment_id = 3;</code>
       * @return Whether the minorFragmentId field is set.
       */
      @java.lang.Override
      public boolean hasMinorFragmentId() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional int32 minor_fragment_id = 3;</code>
       * @return The minorFragmentId.
       */
      @java.lang.Override
      public int getMinorFragmentId() {
        return minorFragmentId_;
      }
      /**
       * <code>optional int32 minor_fragment_id = 3;</code>
       * @param value The minorFragmentId to set.
       * @return This builder for chaining.
       */
      public Builder setMinorFragmentId(int value) {
        bitField0_ |= 0x00000004;
        minorFragmentId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 minor_fragment_id = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearMinorFragmentId() {
        bitField0_ = (bitField0_ & ~0x00000004);
        minorFragmentId_ = 0;
        onChanged();
        return this;
      }

      private java.util.List<org.apache.drill.exec.proto.UserBitShared.OperatorProfile> operatorProfile_ =
        java.util.Collections.emptyList();
      private void ensureOperatorProfileIsMutable() {
        if (!((bitField0_ & 0x00000008) != 0)) {
          operatorProfile_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserBitShared.OperatorProfile>(operatorProfile_);
          bitField0_ |= 0x00000008;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.OperatorProfile, org.apache.drill.exec.proto.UserBitShared.OperatorProfile.Builder, org.apache.drill.exec.proto.UserBitShared.OperatorProfileOrBuilder> operatorProfileBuilder_;

      /**
       * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserBitShared.OperatorProfile> getOperatorProfileList() {
        if (operatorProfileBuilder_ == null) {
          return java.util.Collections.unmodifiableList(operatorProfile_);
        } else {
          return operatorProfileBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
       */
      public int getOperatorProfileCount() {
        if (operatorProfileBuilder_ == null) {
          return operatorProfile_.size();
        } else {
          return operatorProfileBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.OperatorProfile getOperatorProfile(int index) {
        if (operatorProfileBuilder_ == null) {
          return operatorProfile_.get(index);
        } else {
          return operatorProfileBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
       */
      public Builder setOperatorProfile(
          int index, org.apache.drill.exec.proto.UserBitShared.OperatorProfile value) {
        if (operatorProfileBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureOperatorProfileIsMutable();
          operatorProfile_.set(index, value);
          onChanged();
        } else {
          operatorProfileBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
       */
      public Builder setOperatorProfile(
          int index, org.apache.drill.exec.proto.UserBitShared.OperatorProfile.Builder builderForValue) {
        if (operatorProfileBuilder_ == null) {
          ensureOperatorProfileIsMutable();
          operatorProfile_.set(index, builderForValue.build());
          onChanged();
        } else {
          operatorProfileBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
       */
      public Builder addOperatorProfile(org.apache.drill.exec.proto.UserBitShared.OperatorProfile value) {
        if (operatorProfileBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureOperatorProfileIsMutable();
          operatorProfile_.add(value);
          onChanged();
        } else {
          operatorProfileBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
       */
      public Builder addOperatorProfile(
          int index, org.apache.drill.exec.proto.UserBitShared.OperatorProfile value) {
        if (operatorProfileBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureOperatorProfileIsMutable();
          operatorProfile_.add(index, value);
          onChanged();
        } else {
          operatorProfileBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
       */
      public Builder addOperatorProfile(
          org.apache.drill.exec.proto.UserBitShared.OperatorProfile.Builder builderForValue) {
        if (operatorProfileBuilder_ == null) {
          ensureOperatorProfileIsMutable();
          operatorProfile_.add(builderForValue.build());
          onChanged();
        } else {
          operatorProfileBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
       */
      public Builder addOperatorProfile(
          int index, org.apache.drill.exec.proto.UserBitShared.OperatorProfile.Builder builderForValue) {
        if (operatorProfileBuilder_ == null) {
          ensureOperatorProfileIsMutable();
          operatorProfile_.add(index, builderForValue.build());
          onChanged();
        } else {
          operatorProfileBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
       */
      public Builder addAllOperatorProfile(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.UserBitShared.OperatorProfile> values) {
        if (operatorProfileBuilder_ == null) {
          ensureOperatorProfileIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, operatorProfile_);
          onChanged();
        } else {
          operatorProfileBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
       */
      public Builder clearOperatorProfile() {
        if (operatorProfileBuilder_ == null) {
          operatorProfile_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000008);
          onChanged();
        } else {
          operatorProfileBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
       */
      public Builder removeOperatorProfile(int index) {
        if (operatorProfileBuilder_ == null) {
          ensureOperatorProfileIsMutable();
          operatorProfile_.remove(index);
          onChanged();
        } else {
          operatorProfileBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.OperatorProfile.Builder getOperatorProfileBuilder(
          int index) {
        return getOperatorProfileFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.OperatorProfileOrBuilder getOperatorProfileOrBuilder(
          int index) {
        if (operatorProfileBuilder_ == null) {
          return operatorProfile_.get(index);  } else {
          return operatorProfileBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
       */
      public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.OperatorProfileOrBuilder> 
           getOperatorProfileOrBuilderList() {
        if (operatorProfileBuilder_ != null) {
          return operatorProfileBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(operatorProfile_);
        }
      }
      /**
       * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.OperatorProfile.Builder addOperatorProfileBuilder() {
        return getOperatorProfileFieldBuilder().addBuilder(
            org.apache.drill.exec.proto.UserBitShared.OperatorProfile.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.OperatorProfile.Builder addOperatorProfileBuilder(
          int index) {
        return getOperatorProfileFieldBuilder().addBuilder(
            index, org.apache.drill.exec.proto.UserBitShared.OperatorProfile.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserBitShared.OperatorProfile.Builder> 
           getOperatorProfileBuilderList() {
        return getOperatorProfileFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.OperatorProfile, org.apache.drill.exec.proto.UserBitShared.OperatorProfile.Builder, org.apache.drill.exec.proto.UserBitShared.OperatorProfileOrBuilder> 
          getOperatorProfileFieldBuilder() {
        if (operatorProfileBuilder_ == null) {
          operatorProfileBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.OperatorProfile, org.apache.drill.exec.proto.UserBitShared.OperatorProfile.Builder, org.apache.drill.exec.proto.UserBitShared.OperatorProfileOrBuilder>(
                  operatorProfile_,
                  ((bitField0_ & 0x00000008) != 0),
                  getParentForChildren(),
                  isClean());
          operatorProfile_ = null;
        }
        return operatorProfileBuilder_;
      }

      private long startTime_ ;
      /**
       * <code>optional int64 start_time = 5;</code>
       * @return Whether the startTime field is set.
       */
      @java.lang.Override
      public boolean hasStartTime() {
        return ((bitField0_ & 0x00000010) != 0);
      }
      /**
       * <code>optional int64 start_time = 5;</code>
       * @return The startTime.
       */
      @java.lang.Override
      public long getStartTime() {
        return startTime_;
      }
      /**
       * <code>optional int64 start_time = 5;</code>
       * @param value The startTime to set.
       * @return This builder for chaining.
       */
      public Builder setStartTime(long value) {
        bitField0_ |= 0x00000010;
        startTime_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 start_time = 5;</code>
       * @return This builder for chaining.
       */
      public Builder clearStartTime() {
        bitField0_ = (bitField0_ & ~0x00000010);
        startTime_ = 0L;
        onChanged();
        return this;
      }

      private long endTime_ ;
      /**
       * <code>optional int64 end_time = 6;</code>
       * @return Whether the endTime field is set.
       */
      @java.lang.Override
      public boolean hasEndTime() {
        return ((bitField0_ & 0x00000020) != 0);
      }
      /**
       * <code>optional int64 end_time = 6;</code>
       * @return The endTime.
       */
      @java.lang.Override
      public long getEndTime() {
        return endTime_;
      }
      /**
       * <code>optional int64 end_time = 6;</code>
       * @param value The endTime to set.
       * @return This builder for chaining.
       */
      public Builder setEndTime(long value) {
        bitField0_ |= 0x00000020;
        endTime_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 end_time = 6;</code>
       * @return This builder for chaining.
       */
      public Builder clearEndTime() {
        bitField0_ = (bitField0_ & ~0x00000020);
        endTime_ = 0L;
        onChanged();
        return this;
      }

      private long memoryUsed_ ;
      /**
       * <code>optional int64 memory_used = 7;</code>
       * @return Whether the memoryUsed field is set.
       */
      @java.lang.Override
      public boolean hasMemoryUsed() {
        return ((bitField0_ & 0x00000040) != 0);
      }
      /**
       * <code>optional int64 memory_used = 7;</code>
       * @return The memoryUsed.
       */
      @java.lang.Override
      public long getMemoryUsed() {
        return memoryUsed_;
      }
      /**
       * <code>optional int64 memory_used = 7;</code>
       * @param value The memoryUsed to set.
       * @return This builder for chaining.
       */
      public Builder setMemoryUsed(long value) {
        bitField0_ |= 0x00000040;
        memoryUsed_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 memory_used = 7;</code>
       * @return This builder for chaining.
       */
      public Builder clearMemoryUsed() {
        bitField0_ = (bitField0_ & ~0x00000040);
        memoryUsed_ = 0L;
        onChanged();
        return this;
      }

      private long maxMemoryUsed_ ;
      /**
       * <code>optional int64 max_memory_used = 8;</code>
       * @return Whether the maxMemoryUsed field is set.
       */
      @java.lang.Override
      public boolean hasMaxMemoryUsed() {
        return ((bitField0_ & 0x00000080) != 0);
      }
      /**
       * <code>optional int64 max_memory_used = 8;</code>
       * @return The maxMemoryUsed.
       */
      @java.lang.Override
      public long getMaxMemoryUsed() {
        return maxMemoryUsed_;
      }
      /**
       * <code>optional int64 max_memory_used = 8;</code>
       * @param value The maxMemoryUsed to set.
       * @return This builder for chaining.
       */
      public Builder setMaxMemoryUsed(long value) {
        bitField0_ |= 0x00000080;
        maxMemoryUsed_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 max_memory_used = 8;</code>
       * @return This builder for chaining.
       */
      public Builder clearMaxMemoryUsed() {
        bitField0_ = (bitField0_ & ~0x00000080);
        maxMemoryUsed_ = 0L;
        onChanged();
        return this;
      }

      private org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint endpoint_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint, org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder, org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder> endpointBuilder_;
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 9;</code>
       * @return Whether the endpoint field is set.
       */
      public boolean hasEndpoint() {
        return ((bitField0_ & 0x00000100) != 0);
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 9;</code>
       * @return The endpoint.
       */
      public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint getEndpoint() {
        if (endpointBuilder_ == null) {
          return endpoint_ == null ? org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance() : endpoint_;
        } else {
          return endpointBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 9;</code>
       */
      public Builder setEndpoint(org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint value) {
        if (endpointBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          endpoint_ = value;
          onChanged();
        } else {
          endpointBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000100;
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 9;</code>
       */
      public Builder setEndpoint(
          org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder builderForValue) {
        if (endpointBuilder_ == null) {
          endpoint_ = builderForValue.build();
          onChanged();
        } else {
          endpointBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000100;
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 9;</code>
       */
      public Builder mergeEndpoint(org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint value) {
        if (endpointBuilder_ == null) {
          if (((bitField0_ & 0x00000100) != 0) &&
              endpoint_ != null &&
              endpoint_ != org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance()) {
            endpoint_ =
              org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.newBuilder(endpoint_).mergeFrom(value).buildPartial();
          } else {
            endpoint_ = value;
          }
          onChanged();
        } else {
          endpointBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000100;
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 9;</code>
       */
      public Builder clearEndpoint() {
        if (endpointBuilder_ == null) {
          endpoint_ = null;
          onChanged();
        } else {
          endpointBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000100);
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 9;</code>
       */
      public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder getEndpointBuilder() {
        bitField0_ |= 0x00000100;
        onChanged();
        return getEndpointFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 9;</code>
       */
      public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder getEndpointOrBuilder() {
        if (endpointBuilder_ != null) {
          return endpointBuilder_.getMessageOrBuilder();
        } else {
          return endpoint_ == null ?
              org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance() : endpoint_;
        }
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 9;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint, org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder, org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder> 
          getEndpointFieldBuilder() {
        if (endpointBuilder_ == null) {
          endpointBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint, org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder, org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder>(
                  getEndpoint(),
                  getParentForChildren(),
                  isClean());
          endpoint_ = null;
        }
        return endpointBuilder_;
      }

      private long lastUpdate_ ;
      /**
       * <code>optional int64 last_update = 10;</code>
       * @return Whether the lastUpdate field is set.
       */
      @java.lang.Override
      public boolean hasLastUpdate() {
        return ((bitField0_ & 0x00000200) != 0);
      }
      /**
       * <code>optional int64 last_update = 10;</code>
       * @return The lastUpdate.
       */
      @java.lang.Override
      public long getLastUpdate() {
        return lastUpdate_;
      }
      /**
       * <code>optional int64 last_update = 10;</code>
       * @param value The lastUpdate to set.
       * @return This builder for chaining.
       */
      public Builder setLastUpdate(long value) {
        bitField0_ |= 0x00000200;
        lastUpdate_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 last_update = 10;</code>
       * @return This builder for chaining.
       */
      public Builder clearLastUpdate() {
        bitField0_ = (bitField0_ & ~0x00000200);
        lastUpdate_ = 0L;
        onChanged();
        return this;
      }

      private long lastProgress_ ;
      /**
       * <code>optional int64 last_progress = 11;</code>
       * @return Whether the lastProgress field is set.
       */
      @java.lang.Override
      public boolean hasLastProgress() {
        return ((bitField0_ & 0x00000400) != 0);
      }
      /**
       * <code>optional int64 last_progress = 11;</code>
       * @return The lastProgress.
       */
      @java.lang.Override
      public long getLastProgress() {
        return lastProgress_;
      }
      /**
       * <code>optional int64 last_progress = 11;</code>
       * @param value The lastProgress to set.
       * @return This builder for chaining.
       */
      public Builder setLastProgress(long value) {
        bitField0_ |= 0x00000400;
        lastProgress_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 last_progress = 11;</code>
       * @return This builder for chaining.
       */
      public Builder clearLastProgress() {
        bitField0_ = (bitField0_ & ~0x00000400);
        lastProgress_ = 0L;
        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:exec.shared.MinorFragmentProfile)
    }

    // @@protoc_insertion_point(class_scope:exec.shared.MinorFragmentProfile)
    private static final org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile();
    }

    public static org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<MinorFragmentProfile>
        PARSER = new com.google.protobuf.AbstractParser<MinorFragmentProfile>() {
      @java.lang.Override
      public MinorFragmentProfile parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

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

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

    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface OperatorProfileOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.shared.OperatorProfile)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
     */
    java.util.List<org.apache.drill.exec.proto.UserBitShared.StreamProfile> 
        getInputProfileList();
    /**
     * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.StreamProfile getInputProfile(int index);
    /**
     * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
     */
    int getInputProfileCount();
    /**
     * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
     */
    java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.StreamProfileOrBuilder> 
        getInputProfileOrBuilderList();
    /**
     * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.StreamProfileOrBuilder getInputProfileOrBuilder(
        int index);

    /**
     * <code>optional int32 operator_id = 3;</code>
     * @return Whether the operatorId field is set.
     */
    boolean hasOperatorId();
    /**
     * <code>optional int32 operator_id = 3;</code>
     * @return The operatorId.
     */
    int getOperatorId();

    /**
     * <code>optional int32 operator_type = 4 [deprecated = true];</code>
     * @return Whether the operatorType field is set.
     */
    @java.lang.Deprecated boolean hasOperatorType();
    /**
     * <code>optional int32 operator_type = 4 [deprecated = true];</code>
     * @return The operatorType.
     */
    @java.lang.Deprecated int getOperatorType();

    /**
     * <code>optional int64 setup_nanos = 5;</code>
     * @return Whether the setupNanos field is set.
     */
    boolean hasSetupNanos();
    /**
     * <code>optional int64 setup_nanos = 5;</code>
     * @return The setupNanos.
     */
    long getSetupNanos();

    /**
     * <code>optional int64 process_nanos = 6;</code>
     * @return Whether the processNanos field is set.
     */
    boolean hasProcessNanos();
    /**
     * <code>optional int64 process_nanos = 6;</code>
     * @return The processNanos.
     */
    long getProcessNanos();

    /**
     * <code>optional int64 peak_local_memory_allocated = 7;</code>
     * @return Whether the peakLocalMemoryAllocated field is set.
     */
    boolean hasPeakLocalMemoryAllocated();
    /**
     * <code>optional int64 peak_local_memory_allocated = 7;</code>
     * @return The peakLocalMemoryAllocated.
     */
    long getPeakLocalMemoryAllocated();

    /**
     * <code>repeated .exec.shared.MetricValue metric = 8;</code>
     */
    java.util.List<org.apache.drill.exec.proto.UserBitShared.MetricValue> 
        getMetricList();
    /**
     * <code>repeated .exec.shared.MetricValue metric = 8;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.MetricValue getMetric(int index);
    /**
     * <code>repeated .exec.shared.MetricValue metric = 8;</code>
     */
    int getMetricCount();
    /**
     * <code>repeated .exec.shared.MetricValue metric = 8;</code>
     */
    java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.MetricValueOrBuilder> 
        getMetricOrBuilderList();
    /**
     * <code>repeated .exec.shared.MetricValue metric = 8;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.MetricValueOrBuilder getMetricOrBuilder(
        int index);

    /**
     * <code>optional int64 wait_nanos = 9;</code>
     * @return Whether the waitNanos field is set.
     */
    boolean hasWaitNanos();
    /**
     * <code>optional int64 wait_nanos = 9;</code>
     * @return The waitNanos.
     */
    long getWaitNanos();

    /**
     * <code>optional string operator_type_name = 10;</code>
     * @return Whether the operatorTypeName field is set.
     */
    boolean hasOperatorTypeName();
    /**
     * <code>optional string operator_type_name = 10;</code>
     * @return The operatorTypeName.
     */
    java.lang.String getOperatorTypeName();
    /**
     * <code>optional string operator_type_name = 10;</code>
     * @return The bytes for operatorTypeName.
     */
    com.google.protobuf.ByteString
        getOperatorTypeNameBytes();
  }
  /**
   * Protobuf type {@code exec.shared.OperatorProfile}
   */
  public static final class OperatorProfile extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.OperatorProfile)
      OperatorProfileOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use OperatorProfile.newBuilder() to construct.
    private OperatorProfile(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private OperatorProfile() {
      inputProfile_ = java.util.Collections.emptyList();
      metric_ = java.util.Collections.emptyList();
      operatorTypeName_ = "";
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new OperatorProfile();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_OperatorProfile_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_OperatorProfile_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserBitShared.OperatorProfile.class, org.apache.drill.exec.proto.UserBitShared.OperatorProfile.Builder.class);
    }

    private int bitField0_;
    public static final int INPUT_PROFILE_FIELD_NUMBER = 1;
    private java.util.List<org.apache.drill.exec.proto.UserBitShared.StreamProfile> inputProfile_;
    /**
     * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.UserBitShared.StreamProfile> getInputProfileList() {
      return inputProfile_;
    }
    /**
     * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
     */
    @java.lang.Override
    public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.StreamProfileOrBuilder> 
        getInputProfileOrBuilderList() {
      return inputProfile_;
    }
    /**
     * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
     */
    @java.lang.Override
    public int getInputProfileCount() {
      return inputProfile_.size();
    }
    /**
     * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.StreamProfile getInputProfile(int index) {
      return inputProfile_.get(index);
    }
    /**
     * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.StreamProfileOrBuilder getInputProfileOrBuilder(
        int index) {
      return inputProfile_.get(index);
    }

    public static final int OPERATOR_ID_FIELD_NUMBER = 3;
    private int operatorId_;
    /**
     * <code>optional int32 operator_id = 3;</code>
     * @return Whether the operatorId field is set.
     */
    @java.lang.Override
    public boolean hasOperatorId() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional int32 operator_id = 3;</code>
     * @return The operatorId.
     */
    @java.lang.Override
    public int getOperatorId() {
      return operatorId_;
    }

    public static final int OPERATOR_TYPE_FIELD_NUMBER = 4;
    private int operatorType_;
    /**
     * <code>optional int32 operator_type = 4 [deprecated = true];</code>
     * @return Whether the operatorType field is set.
     */
    @java.lang.Override
    @java.lang.Deprecated public boolean hasOperatorType() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional int32 operator_type = 4 [deprecated = true];</code>
     * @return The operatorType.
     */
    @java.lang.Override
    @java.lang.Deprecated public int getOperatorType() {
      return operatorType_;
    }

    public static final int SETUP_NANOS_FIELD_NUMBER = 5;
    private long setupNanos_;
    /**
     * <code>optional int64 setup_nanos = 5;</code>
     * @return Whether the setupNanos field is set.
     */
    @java.lang.Override
    public boolean hasSetupNanos() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional int64 setup_nanos = 5;</code>
     * @return The setupNanos.
     */
    @java.lang.Override
    public long getSetupNanos() {
      return setupNanos_;
    }

    public static final int PROCESS_NANOS_FIELD_NUMBER = 6;
    private long processNanos_;
    /**
     * <code>optional int64 process_nanos = 6;</code>
     * @return Whether the processNanos field is set.
     */
    @java.lang.Override
    public boolean hasProcessNanos() {
      return ((bitField0_ & 0x00000008) != 0);
    }
    /**
     * <code>optional int64 process_nanos = 6;</code>
     * @return The processNanos.
     */
    @java.lang.Override
    public long getProcessNanos() {
      return processNanos_;
    }

    public static final int PEAK_LOCAL_MEMORY_ALLOCATED_FIELD_NUMBER = 7;
    private long peakLocalMemoryAllocated_;
    /**
     * <code>optional int64 peak_local_memory_allocated = 7;</code>
     * @return Whether the peakLocalMemoryAllocated field is set.
     */
    @java.lang.Override
    public boolean hasPeakLocalMemoryAllocated() {
      return ((bitField0_ & 0x00000010) != 0);
    }
    /**
     * <code>optional int64 peak_local_memory_allocated = 7;</code>
     * @return The peakLocalMemoryAllocated.
     */
    @java.lang.Override
    public long getPeakLocalMemoryAllocated() {
      return peakLocalMemoryAllocated_;
    }

    public static final int METRIC_FIELD_NUMBER = 8;
    private java.util.List<org.apache.drill.exec.proto.UserBitShared.MetricValue> metric_;
    /**
     * <code>repeated .exec.shared.MetricValue metric = 8;</code>
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.UserBitShared.MetricValue> getMetricList() {
      return metric_;
    }
    /**
     * <code>repeated .exec.shared.MetricValue metric = 8;</code>
     */
    @java.lang.Override
    public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.MetricValueOrBuilder> 
        getMetricOrBuilderList() {
      return metric_;
    }
    /**
     * <code>repeated .exec.shared.MetricValue metric = 8;</code>
     */
    @java.lang.Override
    public int getMetricCount() {
      return metric_.size();
    }
    /**
     * <code>repeated .exec.shared.MetricValue metric = 8;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.MetricValue getMetric(int index) {
      return metric_.get(index);
    }
    /**
     * <code>repeated .exec.shared.MetricValue metric = 8;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.MetricValueOrBuilder getMetricOrBuilder(
        int index) {
      return metric_.get(index);
    }

    public static final int WAIT_NANOS_FIELD_NUMBER = 9;
    private long waitNanos_;
    /**
     * <code>optional int64 wait_nanos = 9;</code>
     * @return Whether the waitNanos field is set.
     */
    @java.lang.Override
    public boolean hasWaitNanos() {
      return ((bitField0_ & 0x00000020) != 0);
    }
    /**
     * <code>optional int64 wait_nanos = 9;</code>
     * @return The waitNanos.
     */
    @java.lang.Override
    public long getWaitNanos() {
      return waitNanos_;
    }

    public static final int OPERATOR_TYPE_NAME_FIELD_NUMBER = 10;
    private volatile java.lang.Object operatorTypeName_;
    /**
     * <code>optional string operator_type_name = 10;</code>
     * @return Whether the operatorTypeName field is set.
     */
    @java.lang.Override
    public boolean hasOperatorTypeName() {
      return ((bitField0_ & 0x00000040) != 0);
    }
    /**
     * <code>optional string operator_type_name = 10;</code>
     * @return The operatorTypeName.
     */
    @java.lang.Override
    public java.lang.String getOperatorTypeName() {
      java.lang.Object ref = operatorTypeName_;
      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();
        if (bs.isValidUtf8()) {
          operatorTypeName_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string operator_type_name = 10;</code>
     * @return The bytes for operatorTypeName.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getOperatorTypeNameBytes() {
      java.lang.Object ref = operatorTypeName_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        operatorTypeName_ = 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 {
      for (int i = 0; i < inputProfile_.size(); i++) {
        output.writeMessage(1, inputProfile_.get(i));
      }
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeInt32(3, operatorId_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeInt32(4, operatorType_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeInt64(5, setupNanos_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        output.writeInt64(6, processNanos_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        output.writeInt64(7, peakLocalMemoryAllocated_);
      }
      for (int i = 0; i < metric_.size(); i++) {
        output.writeMessage(8, metric_.get(i));
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        output.writeInt64(9, waitNanos_);
      }
      if (((bitField0_ & 0x00000040) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 10, operatorTypeName_);
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      for (int i = 0; i < inputProfile_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, inputProfile_.get(i));
      }
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(3, operatorId_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(4, operatorType_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(5, setupNanos_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(6, processNanos_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(7, peakLocalMemoryAllocated_);
      }
      for (int i = 0; i < metric_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(8, metric_.get(i));
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(9, waitNanos_);
      }
      if (((bitField0_ & 0x00000040) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(10, operatorTypeName_);
      }
      size += getUnknownFields().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.drill.exec.proto.UserBitShared.OperatorProfile)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserBitShared.OperatorProfile other = (org.apache.drill.exec.proto.UserBitShared.OperatorProfile) obj;

      if (!getInputProfileList()
          .equals(other.getInputProfileList())) return false;
      if (hasOperatorId() != other.hasOperatorId()) return false;
      if (hasOperatorId()) {
        if (getOperatorId()
            != other.getOperatorId()) return false;
      }
      if (hasOperatorType() != other.hasOperatorType()) return false;
      if (hasOperatorType()) {
        if (getOperatorType()
            != other.getOperatorType()) return false;
      }
      if (hasSetupNanos() != other.hasSetupNanos()) return false;
      if (hasSetupNanos()) {
        if (getSetupNanos()
            != other.getSetupNanos()) return false;
      }
      if (hasProcessNanos() != other.hasProcessNanos()) return false;
      if (hasProcessNanos()) {
        if (getProcessNanos()
            != other.getProcessNanos()) return false;
      }
      if (hasPeakLocalMemoryAllocated() != other.hasPeakLocalMemoryAllocated()) return false;
      if (hasPeakLocalMemoryAllocated()) {
        if (getPeakLocalMemoryAllocated()
            != other.getPeakLocalMemoryAllocated()) return false;
      }
      if (!getMetricList()
          .equals(other.getMetricList())) return false;
      if (hasWaitNanos() != other.hasWaitNanos()) return false;
      if (hasWaitNanos()) {
        if (getWaitNanos()
            != other.getWaitNanos()) return false;
      }
      if (hasOperatorTypeName() != other.hasOperatorTypeName()) return false;
      if (hasOperatorTypeName()) {
        if (!getOperatorTypeName()
            .equals(other.getOperatorTypeName())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (getInputProfileCount() > 0) {
        hash = (37 * hash) + INPUT_PROFILE_FIELD_NUMBER;
        hash = (53 * hash) + getInputProfileList().hashCode();
      }
      if (hasOperatorId()) {
        hash = (37 * hash) + OPERATOR_ID_FIELD_NUMBER;
        hash = (53 * hash) + getOperatorId();
      }
      if (hasOperatorType()) {
        hash = (37 * hash) + OPERATOR_TYPE_FIELD_NUMBER;
        hash = (53 * hash) + getOperatorType();
      }
      if (hasSetupNanos()) {
        hash = (37 * hash) + SETUP_NANOS_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getSetupNanos());
      }
      if (hasProcessNanos()) {
        hash = (37 * hash) + PROCESS_NANOS_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getProcessNanos());
      }
      if (hasPeakLocalMemoryAllocated()) {
        hash = (37 * hash) + PEAK_LOCAL_MEMORY_ALLOCATED_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getPeakLocalMemoryAllocated());
      }
      if (getMetricCount() > 0) {
        hash = (37 * hash) + METRIC_FIELD_NUMBER;
        hash = (53 * hash) + getMetricList().hashCode();
      }
      if (hasWaitNanos()) {
        hash = (37 * hash) + WAIT_NANOS_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getWaitNanos());
      }
      if (hasOperatorTypeName()) {
        hash = (37 * hash) + OPERATOR_TYPE_NAME_FIELD_NUMBER;
        hash = (53 * hash) + getOperatorTypeName().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserBitShared.OperatorProfile parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.OperatorProfile parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.OperatorProfile parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.OperatorProfile 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.drill.exec.proto.UserBitShared.OperatorProfile parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.OperatorProfile parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.OperatorProfile parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.OperatorProfile 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.drill.exec.proto.UserBitShared.OperatorProfile parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.OperatorProfile 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.drill.exec.proto.UserBitShared.OperatorProfile parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.OperatorProfile 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.drill.exec.proto.UserBitShared.OperatorProfile 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 exec.shared.OperatorProfile}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.shared.OperatorProfile)
        org.apache.drill.exec.proto.UserBitShared.OperatorProfileOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_OperatorProfile_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_OperatorProfile_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserBitShared.OperatorProfile.class, org.apache.drill.exec.proto.UserBitShared.OperatorProfile.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserBitShared.OperatorProfile.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        if (inputProfileBuilder_ == null) {
          inputProfile_ = java.util.Collections.emptyList();
        } else {
          inputProfile_ = null;
          inputProfileBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        operatorId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000002);
        operatorType_ = 0;
        bitField0_ = (bitField0_ & ~0x00000004);
        setupNanos_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000008);
        processNanos_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000010);
        peakLocalMemoryAllocated_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000020);
        if (metricBuilder_ == null) {
          metric_ = java.util.Collections.emptyList();
        } else {
          metric_ = null;
          metricBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000040);
        waitNanos_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000080);
        operatorTypeName_ = "";
        bitField0_ = (bitField0_ & ~0x00000100);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_OperatorProfile_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.OperatorProfile getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserBitShared.OperatorProfile.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.OperatorProfile build() {
        org.apache.drill.exec.proto.UserBitShared.OperatorProfile result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.OperatorProfile buildPartial() {
        org.apache.drill.exec.proto.UserBitShared.OperatorProfile result = new org.apache.drill.exec.proto.UserBitShared.OperatorProfile(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (inputProfileBuilder_ == null) {
          if (((bitField0_ & 0x00000001) != 0)) {
            inputProfile_ = java.util.Collections.unmodifiableList(inputProfile_);
            bitField0_ = (bitField0_ & ~0x00000001);
          }
          result.inputProfile_ = inputProfile_;
        } else {
          result.inputProfile_ = inputProfileBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.operatorId_ = operatorId_;
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.operatorType_ = operatorType_;
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000008) != 0)) {
          result.setupNanos_ = setupNanos_;
          to_bitField0_ |= 0x00000004;
        }
        if (((from_bitField0_ & 0x00000010) != 0)) {
          result.processNanos_ = processNanos_;
          to_bitField0_ |= 0x00000008;
        }
        if (((from_bitField0_ & 0x00000020) != 0)) {
          result.peakLocalMemoryAllocated_ = peakLocalMemoryAllocated_;
          to_bitField0_ |= 0x00000010;
        }
        if (metricBuilder_ == null) {
          if (((bitField0_ & 0x00000040) != 0)) {
            metric_ = java.util.Collections.unmodifiableList(metric_);
            bitField0_ = (bitField0_ & ~0x00000040);
          }
          result.metric_ = metric_;
        } else {
          result.metric_ = metricBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000080) != 0)) {
          result.waitNanos_ = waitNanos_;
          to_bitField0_ |= 0x00000020;
        }
        if (((from_bitField0_ & 0x00000100) != 0)) {
          to_bitField0_ |= 0x00000040;
        }
        result.operatorTypeName_ = operatorTypeName_;
        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.drill.exec.proto.UserBitShared.OperatorProfile) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.OperatorProfile)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.OperatorProfile other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.OperatorProfile.getDefaultInstance()) return this;
        if (inputProfileBuilder_ == null) {
          if (!other.inputProfile_.isEmpty()) {
            if (inputProfile_.isEmpty()) {
              inputProfile_ = other.inputProfile_;
              bitField0_ = (bitField0_ & ~0x00000001);
            } else {
              ensureInputProfileIsMutable();
              inputProfile_.addAll(other.inputProfile_);
            }
            onChanged();
          }
        } else {
          if (!other.inputProfile_.isEmpty()) {
            if (inputProfileBuilder_.isEmpty()) {
              inputProfileBuilder_.dispose();
              inputProfileBuilder_ = null;
              inputProfile_ = other.inputProfile_;
              bitField0_ = (bitField0_ & ~0x00000001);
              inputProfileBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getInputProfileFieldBuilder() : null;
            } else {
              inputProfileBuilder_.addAllMessages(other.inputProfile_);
            }
          }
        }
        if (other.hasOperatorId()) {
          setOperatorId(other.getOperatorId());
        }
        if (other.hasOperatorType()) {
          setOperatorType(other.getOperatorType());
        }
        if (other.hasSetupNanos()) {
          setSetupNanos(other.getSetupNanos());
        }
        if (other.hasProcessNanos()) {
          setProcessNanos(other.getProcessNanos());
        }
        if (other.hasPeakLocalMemoryAllocated()) {
          setPeakLocalMemoryAllocated(other.getPeakLocalMemoryAllocated());
        }
        if (metricBuilder_ == null) {
          if (!other.metric_.isEmpty()) {
            if (metric_.isEmpty()) {
              metric_ = other.metric_;
              bitField0_ = (bitField0_ & ~0x00000040);
            } else {
              ensureMetricIsMutable();
              metric_.addAll(other.metric_);
            }
            onChanged();
          }
        } else {
          if (!other.metric_.isEmpty()) {
            if (metricBuilder_.isEmpty()) {
              metricBuilder_.dispose();
              metricBuilder_ = null;
              metric_ = other.metric_;
              bitField0_ = (bitField0_ & ~0x00000040);
              metricBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getMetricFieldBuilder() : null;
            } else {
              metricBuilder_.addAllMessages(other.metric_);
            }
          }
        }
        if (other.hasWaitNanos()) {
          setWaitNanos(other.getWaitNanos());
        }
        if (other.hasOperatorTypeName()) {
          bitField0_ |= 0x00000100;
          operatorTypeName_ = other.operatorTypeName_;
          onChanged();
        }
        this.mergeUnknownFields(other.getUnknownFields());
        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 {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                org.apache.drill.exec.proto.UserBitShared.StreamProfile m =
                    input.readMessage(
                        org.apache.drill.exec.proto.UserBitShared.StreamProfile.PARSER,
                        extensionRegistry);
                if (inputProfileBuilder_ == null) {
                  ensureInputProfileIsMutable();
                  inputProfile_.add(m);
                } else {
                  inputProfileBuilder_.addMessage(m);
                }
                break;
              } // case 10
              case 24: {
                operatorId_ = input.readInt32();
                bitField0_ |= 0x00000002;
                break;
              } // case 24
              case 32: {
                operatorType_ = input.readInt32();
                bitField0_ |= 0x00000004;
                break;
              } // case 32
              case 40: {
                setupNanos_ = input.readInt64();
                bitField0_ |= 0x00000008;
                break;
              } // case 40
              case 48: {
                processNanos_ = input.readInt64();
                bitField0_ |= 0x00000010;
                break;
              } // case 48
              case 56: {
                peakLocalMemoryAllocated_ = input.readInt64();
                bitField0_ |= 0x00000020;
                break;
              } // case 56
              case 66: {
                org.apache.drill.exec.proto.UserBitShared.MetricValue m =
                    input.readMessage(
                        org.apache.drill.exec.proto.UserBitShared.MetricValue.PARSER,
                        extensionRegistry);
                if (metricBuilder_ == null) {
                  ensureMetricIsMutable();
                  metric_.add(m);
                } else {
                  metricBuilder_.addMessage(m);
                }
                break;
              } // case 66
              case 72: {
                waitNanos_ = input.readInt64();
                bitField0_ |= 0x00000080;
                break;
              } // case 72
              case 82: {
                operatorTypeName_ = input.readBytes();
                bitField0_ |= 0x00000100;
                break;
              } // case 82
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.util.List<org.apache.drill.exec.proto.UserBitShared.StreamProfile> inputProfile_ =
        java.util.Collections.emptyList();
      private void ensureInputProfileIsMutable() {
        if (!((bitField0_ & 0x00000001) != 0)) {
          inputProfile_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserBitShared.StreamProfile>(inputProfile_);
          bitField0_ |= 0x00000001;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.StreamProfile, org.apache.drill.exec.proto.UserBitShared.StreamProfile.Builder, org.apache.drill.exec.proto.UserBitShared.StreamProfileOrBuilder> inputProfileBuilder_;

      /**
       * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserBitShared.StreamProfile> getInputProfileList() {
        if (inputProfileBuilder_ == null) {
          return java.util.Collections.unmodifiableList(inputProfile_);
        } else {
          return inputProfileBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
       */
      public int getInputProfileCount() {
        if (inputProfileBuilder_ == null) {
          return inputProfile_.size();
        } else {
          return inputProfileBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.StreamProfile getInputProfile(int index) {
        if (inputProfileBuilder_ == null) {
          return inputProfile_.get(index);
        } else {
          return inputProfileBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
       */
      public Builder setInputProfile(
          int index, org.apache.drill.exec.proto.UserBitShared.StreamProfile value) {
        if (inputProfileBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureInputProfileIsMutable();
          inputProfile_.set(index, value);
          onChanged();
        } else {
          inputProfileBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
       */
      public Builder setInputProfile(
          int index, org.apache.drill.exec.proto.UserBitShared.StreamProfile.Builder builderForValue) {
        if (inputProfileBuilder_ == null) {
          ensureInputProfileIsMutable();
          inputProfile_.set(index, builderForValue.build());
          onChanged();
        } else {
          inputProfileBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
       */
      public Builder addInputProfile(org.apache.drill.exec.proto.UserBitShared.StreamProfile value) {
        if (inputProfileBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureInputProfileIsMutable();
          inputProfile_.add(value);
          onChanged();
        } else {
          inputProfileBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
       */
      public Builder addInputProfile(
          int index, org.apache.drill.exec.proto.UserBitShared.StreamProfile value) {
        if (inputProfileBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureInputProfileIsMutable();
          inputProfile_.add(index, value);
          onChanged();
        } else {
          inputProfileBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
       */
      public Builder addInputProfile(
          org.apache.drill.exec.proto.UserBitShared.StreamProfile.Builder builderForValue) {
        if (inputProfileBuilder_ == null) {
          ensureInputProfileIsMutable();
          inputProfile_.add(builderForValue.build());
          onChanged();
        } else {
          inputProfileBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
       */
      public Builder addInputProfile(
          int index, org.apache.drill.exec.proto.UserBitShared.StreamProfile.Builder builderForValue) {
        if (inputProfileBuilder_ == null) {
          ensureInputProfileIsMutable();
          inputProfile_.add(index, builderForValue.build());
          onChanged();
        } else {
          inputProfileBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
       */
      public Builder addAllInputProfile(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.UserBitShared.StreamProfile> values) {
        if (inputProfileBuilder_ == null) {
          ensureInputProfileIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, inputProfile_);
          onChanged();
        } else {
          inputProfileBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
       */
      public Builder clearInputProfile() {
        if (inputProfileBuilder_ == null) {
          inputProfile_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
          onChanged();
        } else {
          inputProfileBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
       */
      public Builder removeInputProfile(int index) {
        if (inputProfileBuilder_ == null) {
          ensureInputProfileIsMutable();
          inputProfile_.remove(index);
          onChanged();
        } else {
          inputProfileBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.StreamProfile.Builder getInputProfileBuilder(
          int index) {
        return getInputProfileFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.StreamProfileOrBuilder getInputProfileOrBuilder(
          int index) {
        if (inputProfileBuilder_ == null) {
          return inputProfile_.get(index);  } else {
          return inputProfileBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
       */
      public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.StreamProfileOrBuilder> 
           getInputProfileOrBuilderList() {
        if (inputProfileBuilder_ != null) {
          return inputProfileBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(inputProfile_);
        }
      }
      /**
       * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.StreamProfile.Builder addInputProfileBuilder() {
        return getInputProfileFieldBuilder().addBuilder(
            org.apache.drill.exec.proto.UserBitShared.StreamProfile.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.StreamProfile.Builder addInputProfileBuilder(
          int index) {
        return getInputProfileFieldBuilder().addBuilder(
            index, org.apache.drill.exec.proto.UserBitShared.StreamProfile.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserBitShared.StreamProfile.Builder> 
           getInputProfileBuilderList() {
        return getInputProfileFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.StreamProfile, org.apache.drill.exec.proto.UserBitShared.StreamProfile.Builder, org.apache.drill.exec.proto.UserBitShared.StreamProfileOrBuilder> 
          getInputProfileFieldBuilder() {
        if (inputProfileBuilder_ == null) {
          inputProfileBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.StreamProfile, org.apache.drill.exec.proto.UserBitShared.StreamProfile.Builder, org.apache.drill.exec.proto.UserBitShared.StreamProfileOrBuilder>(
                  inputProfile_,
                  ((bitField0_ & 0x00000001) != 0),
                  getParentForChildren(),
                  isClean());
          inputProfile_ = null;
        }
        return inputProfileBuilder_;
      }

      private int operatorId_ ;
      /**
       * <code>optional int32 operator_id = 3;</code>
       * @return Whether the operatorId field is set.
       */
      @java.lang.Override
      public boolean hasOperatorId() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional int32 operator_id = 3;</code>
       * @return The operatorId.
       */
      @java.lang.Override
      public int getOperatorId() {
        return operatorId_;
      }
      /**
       * <code>optional int32 operator_id = 3;</code>
       * @param value The operatorId to set.
       * @return This builder for chaining.
       */
      public Builder setOperatorId(int value) {
        bitField0_ |= 0x00000002;
        operatorId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 operator_id = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearOperatorId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        operatorId_ = 0;
        onChanged();
        return this;
      }

      private int operatorType_ ;
      /**
       * <code>optional int32 operator_type = 4 [deprecated = true];</code>
       * @return Whether the operatorType field is set.
       */
      @java.lang.Override
      @java.lang.Deprecated public boolean hasOperatorType() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional int32 operator_type = 4 [deprecated = true];</code>
       * @return The operatorType.
       */
      @java.lang.Override
      @java.lang.Deprecated public int getOperatorType() {
        return operatorType_;
      }
      /**
       * <code>optional int32 operator_type = 4 [deprecated = true];</code>
       * @param value The operatorType to set.
       * @return This builder for chaining.
       */
      @java.lang.Deprecated public Builder setOperatorType(int value) {
        bitField0_ |= 0x00000004;
        operatorType_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 operator_type = 4 [deprecated = true];</code>
       * @return This builder for chaining.
       */
      @java.lang.Deprecated public Builder clearOperatorType() {
        bitField0_ = (bitField0_ & ~0x00000004);
        operatorType_ = 0;
        onChanged();
        return this;
      }

      private long setupNanos_ ;
      /**
       * <code>optional int64 setup_nanos = 5;</code>
       * @return Whether the setupNanos field is set.
       */
      @java.lang.Override
      public boolean hasSetupNanos() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <code>optional int64 setup_nanos = 5;</code>
       * @return The setupNanos.
       */
      @java.lang.Override
      public long getSetupNanos() {
        return setupNanos_;
      }
      /**
       * <code>optional int64 setup_nanos = 5;</code>
       * @param value The setupNanos to set.
       * @return This builder for chaining.
       */
      public Builder setSetupNanos(long value) {
        bitField0_ |= 0x00000008;
        setupNanos_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 setup_nanos = 5;</code>
       * @return This builder for chaining.
       */
      public Builder clearSetupNanos() {
        bitField0_ = (bitField0_ & ~0x00000008);
        setupNanos_ = 0L;
        onChanged();
        return this;
      }

      private long processNanos_ ;
      /**
       * <code>optional int64 process_nanos = 6;</code>
       * @return Whether the processNanos field is set.
       */
      @java.lang.Override
      public boolean hasProcessNanos() {
        return ((bitField0_ & 0x00000010) != 0);
      }
      /**
       * <code>optional int64 process_nanos = 6;</code>
       * @return The processNanos.
       */
      @java.lang.Override
      public long getProcessNanos() {
        return processNanos_;
      }
      /**
       * <code>optional int64 process_nanos = 6;</code>
       * @param value The processNanos to set.
       * @return This builder for chaining.
       */
      public Builder setProcessNanos(long value) {
        bitField0_ |= 0x00000010;
        processNanos_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 process_nanos = 6;</code>
       * @return This builder for chaining.
       */
      public Builder clearProcessNanos() {
        bitField0_ = (bitField0_ & ~0x00000010);
        processNanos_ = 0L;
        onChanged();
        return this;
      }

      private long peakLocalMemoryAllocated_ ;
      /**
       * <code>optional int64 peak_local_memory_allocated = 7;</code>
       * @return Whether the peakLocalMemoryAllocated field is set.
       */
      @java.lang.Override
      public boolean hasPeakLocalMemoryAllocated() {
        return ((bitField0_ & 0x00000020) != 0);
      }
      /**
       * <code>optional int64 peak_local_memory_allocated = 7;</code>
       * @return The peakLocalMemoryAllocated.
       */
      @java.lang.Override
      public long getPeakLocalMemoryAllocated() {
        return peakLocalMemoryAllocated_;
      }
      /**
       * <code>optional int64 peak_local_memory_allocated = 7;</code>
       * @param value The peakLocalMemoryAllocated to set.
       * @return This builder for chaining.
       */
      public Builder setPeakLocalMemoryAllocated(long value) {
        bitField0_ |= 0x00000020;
        peakLocalMemoryAllocated_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 peak_local_memory_allocated = 7;</code>
       * @return This builder for chaining.
       */
      public Builder clearPeakLocalMemoryAllocated() {
        bitField0_ = (bitField0_ & ~0x00000020);
        peakLocalMemoryAllocated_ = 0L;
        onChanged();
        return this;
      }

      private java.util.List<org.apache.drill.exec.proto.UserBitShared.MetricValue> metric_ =
        java.util.Collections.emptyList();
      private void ensureMetricIsMutable() {
        if (!((bitField0_ & 0x00000040) != 0)) {
          metric_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserBitShared.MetricValue>(metric_);
          bitField0_ |= 0x00000040;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.MetricValue, org.apache.drill.exec.proto.UserBitShared.MetricValue.Builder, org.apache.drill.exec.proto.UserBitShared.MetricValueOrBuilder> metricBuilder_;

      /**
       * <code>repeated .exec.shared.MetricValue metric = 8;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserBitShared.MetricValue> getMetricList() {
        if (metricBuilder_ == null) {
          return java.util.Collections.unmodifiableList(metric_);
        } else {
          return metricBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .exec.shared.MetricValue metric = 8;</code>
       */
      public int getMetricCount() {
        if (metricBuilder_ == null) {
          return metric_.size();
        } else {
          return metricBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .exec.shared.MetricValue metric = 8;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.MetricValue getMetric(int index) {
        if (metricBuilder_ == null) {
          return metric_.get(index);
        } else {
          return metricBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .exec.shared.MetricValue metric = 8;</code>
       */
      public Builder setMetric(
          int index, org.apache.drill.exec.proto.UserBitShared.MetricValue value) {
        if (metricBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureMetricIsMutable();
          metric_.set(index, value);
          onChanged();
        } else {
          metricBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MetricValue metric = 8;</code>
       */
      public Builder setMetric(
          int index, org.apache.drill.exec.proto.UserBitShared.MetricValue.Builder builderForValue) {
        if (metricBuilder_ == null) {
          ensureMetricIsMutable();
          metric_.set(index, builderForValue.build());
          onChanged();
        } else {
          metricBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MetricValue metric = 8;</code>
       */
      public Builder addMetric(org.apache.drill.exec.proto.UserBitShared.MetricValue value) {
        if (metricBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureMetricIsMutable();
          metric_.add(value);
          onChanged();
        } else {
          metricBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MetricValue metric = 8;</code>
       */
      public Builder addMetric(
          int index, org.apache.drill.exec.proto.UserBitShared.MetricValue value) {
        if (metricBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureMetricIsMutable();
          metric_.add(index, value);
          onChanged();
        } else {
          metricBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MetricValue metric = 8;</code>
       */
      public Builder addMetric(
          org.apache.drill.exec.proto.UserBitShared.MetricValue.Builder builderForValue) {
        if (metricBuilder_ == null) {
          ensureMetricIsMutable();
          metric_.add(builderForValue.build());
          onChanged();
        } else {
          metricBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MetricValue metric = 8;</code>
       */
      public Builder addMetric(
          int index, org.apache.drill.exec.proto.UserBitShared.MetricValue.Builder builderForValue) {
        if (metricBuilder_ == null) {
          ensureMetricIsMutable();
          metric_.add(index, builderForValue.build());
          onChanged();
        } else {
          metricBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MetricValue metric = 8;</code>
       */
      public Builder addAllMetric(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.UserBitShared.MetricValue> values) {
        if (metricBuilder_ == null) {
          ensureMetricIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, metric_);
          onChanged();
        } else {
          metricBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MetricValue metric = 8;</code>
       */
      public Builder clearMetric() {
        if (metricBuilder_ == null) {
          metric_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000040);
          onChanged();
        } else {
          metricBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MetricValue metric = 8;</code>
       */
      public Builder removeMetric(int index) {
        if (metricBuilder_ == null) {
          ensureMetricIsMutable();
          metric_.remove(index);
          onChanged();
        } else {
          metricBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.MetricValue metric = 8;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.MetricValue.Builder getMetricBuilder(
          int index) {
        return getMetricFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .exec.shared.MetricValue metric = 8;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.MetricValueOrBuilder getMetricOrBuilder(
          int index) {
        if (metricBuilder_ == null) {
          return metric_.get(index);  } else {
          return metricBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .exec.shared.MetricValue metric = 8;</code>
       */
      public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.MetricValueOrBuilder> 
           getMetricOrBuilderList() {
        if (metricBuilder_ != null) {
          return metricBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(metric_);
        }
      }
      /**
       * <code>repeated .exec.shared.MetricValue metric = 8;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.MetricValue.Builder addMetricBuilder() {
        return getMetricFieldBuilder().addBuilder(
            org.apache.drill.exec.proto.UserBitShared.MetricValue.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.shared.MetricValue metric = 8;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.MetricValue.Builder addMetricBuilder(
          int index) {
        return getMetricFieldBuilder().addBuilder(
            index, org.apache.drill.exec.proto.UserBitShared.MetricValue.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.shared.MetricValue metric = 8;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserBitShared.MetricValue.Builder> 
           getMetricBuilderList() {
        return getMetricFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.MetricValue, org.apache.drill.exec.proto.UserBitShared.MetricValue.Builder, org.apache.drill.exec.proto.UserBitShared.MetricValueOrBuilder> 
          getMetricFieldBuilder() {
        if (metricBuilder_ == null) {
          metricBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.MetricValue, org.apache.drill.exec.proto.UserBitShared.MetricValue.Builder, org.apache.drill.exec.proto.UserBitShared.MetricValueOrBuilder>(
                  metric_,
                  ((bitField0_ & 0x00000040) != 0),
                  getParentForChildren(),
                  isClean());
          metric_ = null;
        }
        return metricBuilder_;
      }

      private long waitNanos_ ;
      /**
       * <code>optional int64 wait_nanos = 9;</code>
       * @return Whether the waitNanos field is set.
       */
      @java.lang.Override
      public boolean hasWaitNanos() {
        return ((bitField0_ & 0x00000080) != 0);
      }
      /**
       * <code>optional int64 wait_nanos = 9;</code>
       * @return The waitNanos.
       */
      @java.lang.Override
      public long getWaitNanos() {
        return waitNanos_;
      }
      /**
       * <code>optional int64 wait_nanos = 9;</code>
       * @param value The waitNanos to set.
       * @return This builder for chaining.
       */
      public Builder setWaitNanos(long value) {
        bitField0_ |= 0x00000080;
        waitNanos_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 wait_nanos = 9;</code>
       * @return This builder for chaining.
       */
      public Builder clearWaitNanos() {
        bitField0_ = (bitField0_ & ~0x00000080);
        waitNanos_ = 0L;
        onChanged();
        return this;
      }

      private java.lang.Object operatorTypeName_ = "";
      /**
       * <code>optional string operator_type_name = 10;</code>
       * @return Whether the operatorTypeName field is set.
       */
      public boolean hasOperatorTypeName() {
        return ((bitField0_ & 0x00000100) != 0);
      }
      /**
       * <code>optional string operator_type_name = 10;</code>
       * @return The operatorTypeName.
       */
      public java.lang.String getOperatorTypeName() {
        java.lang.Object ref = operatorTypeName_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            operatorTypeName_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string operator_type_name = 10;</code>
       * @return The bytes for operatorTypeName.
       */
      public com.google.protobuf.ByteString
          getOperatorTypeNameBytes() {
        java.lang.Object ref = operatorTypeName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          operatorTypeName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string operator_type_name = 10;</code>
       * @param value The operatorTypeName to set.
       * @return This builder for chaining.
       */
      public Builder setOperatorTypeName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000100;
        operatorTypeName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string operator_type_name = 10;</code>
       * @return This builder for chaining.
       */
      public Builder clearOperatorTypeName() {
        bitField0_ = (bitField0_ & ~0x00000100);
        operatorTypeName_ = getDefaultInstance().getOperatorTypeName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string operator_type_name = 10;</code>
       * @param value The bytes for operatorTypeName to set.
       * @return This builder for chaining.
       */
      public Builder setOperatorTypeNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000100;
        operatorTypeName_ = 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:exec.shared.OperatorProfile)
    }

    // @@protoc_insertion_point(class_scope:exec.shared.OperatorProfile)
    private static final org.apache.drill.exec.proto.UserBitShared.OperatorProfile DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserBitShared.OperatorProfile();
    }

    public static org.apache.drill.exec.proto.UserBitShared.OperatorProfile getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<OperatorProfile>
        PARSER = new com.google.protobuf.AbstractParser<OperatorProfile>() {
      @java.lang.Override
      public OperatorProfile parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

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

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

    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.OperatorProfile getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface StreamProfileOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.shared.StreamProfile)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional int64 records = 1;</code>
     * @return Whether the records field is set.
     */
    boolean hasRecords();
    /**
     * <code>optional int64 records = 1;</code>
     * @return The records.
     */
    long getRecords();

    /**
     * <code>optional int64 batches = 2;</code>
     * @return Whether the batches field is set.
     */
    boolean hasBatches();
    /**
     * <code>optional int64 batches = 2;</code>
     * @return The batches.
     */
    long getBatches();

    /**
     * <code>optional int64 schemas = 3;</code>
     * @return Whether the schemas field is set.
     */
    boolean hasSchemas();
    /**
     * <code>optional int64 schemas = 3;</code>
     * @return The schemas.
     */
    long getSchemas();
  }
  /**
   * Protobuf type {@code exec.shared.StreamProfile}
   */
  public static final class StreamProfile extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.StreamProfile)
      StreamProfileOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use StreamProfile.newBuilder() to construct.
    private StreamProfile(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private StreamProfile() {
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new StreamProfile();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_StreamProfile_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_StreamProfile_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserBitShared.StreamProfile.class, org.apache.drill.exec.proto.UserBitShared.StreamProfile.Builder.class);
    }

    private int bitField0_;
    public static final int RECORDS_FIELD_NUMBER = 1;
    private long records_;
    /**
     * <code>optional int64 records = 1;</code>
     * @return Whether the records field is set.
     */
    @java.lang.Override
    public boolean hasRecords() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional int64 records = 1;</code>
     * @return The records.
     */
    @java.lang.Override
    public long getRecords() {
      return records_;
    }

    public static final int BATCHES_FIELD_NUMBER = 2;
    private long batches_;
    /**
     * <code>optional int64 batches = 2;</code>
     * @return Whether the batches field is set.
     */
    @java.lang.Override
    public boolean hasBatches() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional int64 batches = 2;</code>
     * @return The batches.
     */
    @java.lang.Override
    public long getBatches() {
      return batches_;
    }

    public static final int SCHEMAS_FIELD_NUMBER = 3;
    private long schemas_;
    /**
     * <code>optional int64 schemas = 3;</code>
     * @return Whether the schemas field is set.
     */
    @java.lang.Override
    public boolean hasSchemas() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional int64 schemas = 3;</code>
     * @return The schemas.
     */
    @java.lang.Override
    public long getSchemas() {
      return schemas_;
    }

    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 (((bitField0_ & 0x00000001) != 0)) {
        output.writeInt64(1, records_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeInt64(2, batches_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeInt64(3, schemas_);
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(1, records_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, batches_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(3, schemas_);
      }
      size += getUnknownFields().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.drill.exec.proto.UserBitShared.StreamProfile)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserBitShared.StreamProfile other = (org.apache.drill.exec.proto.UserBitShared.StreamProfile) obj;

      if (hasRecords() != other.hasRecords()) return false;
      if (hasRecords()) {
        if (getRecords()
            != other.getRecords()) return false;
      }
      if (hasBatches() != other.hasBatches()) return false;
      if (hasBatches()) {
        if (getBatches()
            != other.getBatches()) return false;
      }
      if (hasSchemas() != other.hasSchemas()) return false;
      if (hasSchemas()) {
        if (getSchemas()
            != other.getSchemas()) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasRecords()) {
        hash = (37 * hash) + RECORDS_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getRecords());
      }
      if (hasBatches()) {
        hash = (37 * hash) + BATCHES_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getBatches());
      }
      if (hasSchemas()) {
        hash = (37 * hash) + SCHEMAS_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getSchemas());
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserBitShared.StreamProfile parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.StreamProfile parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.StreamProfile parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.StreamProfile 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.drill.exec.proto.UserBitShared.StreamProfile parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.StreamProfile parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.StreamProfile parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.StreamProfile 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.drill.exec.proto.UserBitShared.StreamProfile parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.StreamProfile 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.drill.exec.proto.UserBitShared.StreamProfile parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.StreamProfile 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.drill.exec.proto.UserBitShared.StreamProfile 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 exec.shared.StreamProfile}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.shared.StreamProfile)
        org.apache.drill.exec.proto.UserBitShared.StreamProfileOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_StreamProfile_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_StreamProfile_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserBitShared.StreamProfile.class, org.apache.drill.exec.proto.UserBitShared.StreamProfile.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserBitShared.StreamProfile.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        records_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000001);
        batches_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        schemas_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_StreamProfile_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.StreamProfile getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserBitShared.StreamProfile.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.StreamProfile build() {
        org.apache.drill.exec.proto.UserBitShared.StreamProfile result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.StreamProfile buildPartial() {
        org.apache.drill.exec.proto.UserBitShared.StreamProfile result = new org.apache.drill.exec.proto.UserBitShared.StreamProfile(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.records_ = records_;
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.batches_ = batches_;
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.schemas_ = schemas_;
          to_bitField0_ |= 0x00000004;
        }
        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.drill.exec.proto.UserBitShared.StreamProfile) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.StreamProfile)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.StreamProfile other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.StreamProfile.getDefaultInstance()) return this;
        if (other.hasRecords()) {
          setRecords(other.getRecords());
        }
        if (other.hasBatches()) {
          setBatches(other.getBatches());
        }
        if (other.hasSchemas()) {
          setSchemas(other.getSchemas());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        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 {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                records_ = input.readInt64();
                bitField0_ |= 0x00000001;
                break;
              } // case 8
              case 16: {
                batches_ = input.readInt64();
                bitField0_ |= 0x00000002;
                break;
              } // case 16
              case 24: {
                schemas_ = input.readInt64();
                bitField0_ |= 0x00000004;
                break;
              } // case 24
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private long records_ ;
      /**
       * <code>optional int64 records = 1;</code>
       * @return Whether the records field is set.
       */
      @java.lang.Override
      public boolean hasRecords() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional int64 records = 1;</code>
       * @return The records.
       */
      @java.lang.Override
      public long getRecords() {
        return records_;
      }
      /**
       * <code>optional int64 records = 1;</code>
       * @param value The records to set.
       * @return This builder for chaining.
       */
      public Builder setRecords(long value) {
        bitField0_ |= 0x00000001;
        records_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 records = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearRecords() {
        bitField0_ = (bitField0_ & ~0x00000001);
        records_ = 0L;
        onChanged();
        return this;
      }

      private long batches_ ;
      /**
       * <code>optional int64 batches = 2;</code>
       * @return Whether the batches field is set.
       */
      @java.lang.Override
      public boolean hasBatches() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional int64 batches = 2;</code>
       * @return The batches.
       */
      @java.lang.Override
      public long getBatches() {
        return batches_;
      }
      /**
       * <code>optional int64 batches = 2;</code>
       * @param value The batches to set.
       * @return This builder for chaining.
       */
      public Builder setBatches(long value) {
        bitField0_ |= 0x00000002;
        batches_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 batches = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearBatches() {
        bitField0_ = (bitField0_ & ~0x00000002);
        batches_ = 0L;
        onChanged();
        return this;
      }

      private long schemas_ ;
      /**
       * <code>optional int64 schemas = 3;</code>
       * @return Whether the schemas field is set.
       */
      @java.lang.Override
      public boolean hasSchemas() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional int64 schemas = 3;</code>
       * @return The schemas.
       */
      @java.lang.Override
      public long getSchemas() {
        return schemas_;
      }
      /**
       * <code>optional int64 schemas = 3;</code>
       * @param value The schemas to set.
       * @return This builder for chaining.
       */
      public Builder setSchemas(long value) {
        bitField0_ |= 0x00000004;
        schemas_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 schemas = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearSchemas() {
        bitField0_ = (bitField0_ & ~0x00000004);
        schemas_ = 0L;
        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:exec.shared.StreamProfile)
    }

    // @@protoc_insertion_point(class_scope:exec.shared.StreamProfile)
    private static final org.apache.drill.exec.proto.UserBitShared.StreamProfile DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserBitShared.StreamProfile();
    }

    public static org.apache.drill.exec.proto.UserBitShared.StreamProfile getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<StreamProfile>
        PARSER = new com.google.protobuf.AbstractParser<StreamProfile>() {
      @java.lang.Override
      public StreamProfile parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

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

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

    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.StreamProfile getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface MetricValueOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.shared.MetricValue)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional int32 metric_id = 1;</code>
     * @return Whether the metricId field is set.
     */
    boolean hasMetricId();
    /**
     * <code>optional int32 metric_id = 1;</code>
     * @return The metricId.
     */
    int getMetricId();

    /**
     * <code>optional int64 long_value = 2;</code>
     * @return Whether the longValue field is set.
     */
    boolean hasLongValue();
    /**
     * <code>optional int64 long_value = 2;</code>
     * @return The longValue.
     */
    long getLongValue();

    /**
     * <code>optional double double_value = 3;</code>
     * @return Whether the doubleValue field is set.
     */
    boolean hasDoubleValue();
    /**
     * <code>optional double double_value = 3;</code>
     * @return The doubleValue.
     */
    double getDoubleValue();
  }
  /**
   * Protobuf type {@code exec.shared.MetricValue}
   */
  public static final class MetricValue extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.MetricValue)
      MetricValueOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use MetricValue.newBuilder() to construct.
    private MetricValue(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private MetricValue() {
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new MetricValue();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_MetricValue_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_MetricValue_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserBitShared.MetricValue.class, org.apache.drill.exec.proto.UserBitShared.MetricValue.Builder.class);
    }

    private int bitField0_;
    public static final int METRIC_ID_FIELD_NUMBER = 1;
    private int metricId_;
    /**
     * <code>optional int32 metric_id = 1;</code>
     * @return Whether the metricId field is set.
     */
    @java.lang.Override
    public boolean hasMetricId() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional int32 metric_id = 1;</code>
     * @return The metricId.
     */
    @java.lang.Override
    public int getMetricId() {
      return metricId_;
    }

    public static final int LONG_VALUE_FIELD_NUMBER = 2;
    private long longValue_;
    /**
     * <code>optional int64 long_value = 2;</code>
     * @return Whether the longValue field is set.
     */
    @java.lang.Override
    public boolean hasLongValue() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional int64 long_value = 2;</code>
     * @return The longValue.
     */
    @java.lang.Override
    public long getLongValue() {
      return longValue_;
    }

    public static final int DOUBLE_VALUE_FIELD_NUMBER = 3;
    private double doubleValue_;
    /**
     * <code>optional double double_value = 3;</code>
     * @return Whether the doubleValue field is set.
     */
    @java.lang.Override
    public boolean hasDoubleValue() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional double double_value = 3;</code>
     * @return The doubleValue.
     */
    @java.lang.Override
    public double getDoubleValue() {
      return doubleValue_;
    }

    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 (((bitField0_ & 0x00000001) != 0)) {
        output.writeInt32(1, metricId_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeInt64(2, longValue_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeDouble(3, doubleValue_);
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(1, metricId_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, longValue_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeDoubleSize(3, doubleValue_);
      }
      size += getUnknownFields().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.drill.exec.proto.UserBitShared.MetricValue)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserBitShared.MetricValue other = (org.apache.drill.exec.proto.UserBitShared.MetricValue) obj;

      if (hasMetricId() != other.hasMetricId()) return false;
      if (hasMetricId()) {
        if (getMetricId()
            != other.getMetricId()) return false;
      }
      if (hasLongValue() != other.hasLongValue()) return false;
      if (hasLongValue()) {
        if (getLongValue()
            != other.getLongValue()) return false;
      }
      if (hasDoubleValue() != other.hasDoubleValue()) return false;
      if (hasDoubleValue()) {
        if (java.lang.Double.doubleToLongBits(getDoubleValue())
            != java.lang.Double.doubleToLongBits(
                other.getDoubleValue())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasMetricId()) {
        hash = (37 * hash) + METRIC_ID_FIELD_NUMBER;
        hash = (53 * hash) + getMetricId();
      }
      if (hasLongValue()) {
        hash = (37 * hash) + LONG_VALUE_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getLongValue());
      }
      if (hasDoubleValue()) {
        hash = (37 * hash) + DOUBLE_VALUE_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            java.lang.Double.doubleToLongBits(getDoubleValue()));
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserBitShared.MetricValue parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.MetricValue parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.MetricValue parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.MetricValue 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.drill.exec.proto.UserBitShared.MetricValue parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.MetricValue parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.MetricValue parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.MetricValue 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.drill.exec.proto.UserBitShared.MetricValue parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.MetricValue 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.drill.exec.proto.UserBitShared.MetricValue parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.MetricValue 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.drill.exec.proto.UserBitShared.MetricValue 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 exec.shared.MetricValue}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.shared.MetricValue)
        org.apache.drill.exec.proto.UserBitShared.MetricValueOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_MetricValue_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_MetricValue_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserBitShared.MetricValue.class, org.apache.drill.exec.proto.UserBitShared.MetricValue.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserBitShared.MetricValue.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        metricId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        longValue_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        doubleValue_ = 0D;
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_MetricValue_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.MetricValue getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserBitShared.MetricValue.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.MetricValue build() {
        org.apache.drill.exec.proto.UserBitShared.MetricValue result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.MetricValue buildPartial() {
        org.apache.drill.exec.proto.UserBitShared.MetricValue result = new org.apache.drill.exec.proto.UserBitShared.MetricValue(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.metricId_ = metricId_;
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.longValue_ = longValue_;
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.doubleValue_ = doubleValue_;
          to_bitField0_ |= 0x00000004;
        }
        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.drill.exec.proto.UserBitShared.MetricValue) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.MetricValue)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.MetricValue other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.MetricValue.getDefaultInstance()) return this;
        if (other.hasMetricId()) {
          setMetricId(other.getMetricId());
        }
        if (other.hasLongValue()) {
          setLongValue(other.getLongValue());
        }
        if (other.hasDoubleValue()) {
          setDoubleValue(other.getDoubleValue());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        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 {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                metricId_ = input.readInt32();
                bitField0_ |= 0x00000001;
                break;
              } // case 8
              case 16: {
                longValue_ = input.readInt64();
                bitField0_ |= 0x00000002;
                break;
              } // case 16
              case 25: {
                doubleValue_ = input.readDouble();
                bitField0_ |= 0x00000004;
                break;
              } // case 25
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private int metricId_ ;
      /**
       * <code>optional int32 metric_id = 1;</code>
       * @return Whether the metricId field is set.
       */
      @java.lang.Override
      public boolean hasMetricId() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional int32 metric_id = 1;</code>
       * @return The metricId.
       */
      @java.lang.Override
      public int getMetricId() {
        return metricId_;
      }
      /**
       * <code>optional int32 metric_id = 1;</code>
       * @param value The metricId to set.
       * @return This builder for chaining.
       */
      public Builder setMetricId(int value) {
        bitField0_ |= 0x00000001;
        metricId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 metric_id = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearMetricId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        metricId_ = 0;
        onChanged();
        return this;
      }

      private long longValue_ ;
      /**
       * <code>optional int64 long_value = 2;</code>
       * @return Whether the longValue field is set.
       */
      @java.lang.Override
      public boolean hasLongValue() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional int64 long_value = 2;</code>
       * @return The longValue.
       */
      @java.lang.Override
      public long getLongValue() {
        return longValue_;
      }
      /**
       * <code>optional int64 long_value = 2;</code>
       * @param value The longValue to set.
       * @return This builder for chaining.
       */
      public Builder setLongValue(long value) {
        bitField0_ |= 0x00000002;
        longValue_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 long_value = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearLongValue() {
        bitField0_ = (bitField0_ & ~0x00000002);
        longValue_ = 0L;
        onChanged();
        return this;
      }

      private double doubleValue_ ;
      /**
       * <code>optional double double_value = 3;</code>
       * @return Whether the doubleValue field is set.
       */
      @java.lang.Override
      public boolean hasDoubleValue() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional double double_value = 3;</code>
       * @return The doubleValue.
       */
      @java.lang.Override
      public double getDoubleValue() {
        return doubleValue_;
      }
      /**
       * <code>optional double double_value = 3;</code>
       * @param value The doubleValue to set.
       * @return This builder for chaining.
       */
      public Builder setDoubleValue(double value) {
        bitField0_ |= 0x00000004;
        doubleValue_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional double double_value = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearDoubleValue() {
        bitField0_ = (bitField0_ & ~0x00000004);
        doubleValue_ = 0D;
        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:exec.shared.MetricValue)
    }

    // @@protoc_insertion_point(class_scope:exec.shared.MetricValue)
    private static final org.apache.drill.exec.proto.UserBitShared.MetricValue DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserBitShared.MetricValue();
    }

    public static org.apache.drill.exec.proto.UserBitShared.MetricValue getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<MetricValue>
        PARSER = new com.google.protobuf.AbstractParser<MetricValue>() {
      @java.lang.Override
      public MetricValue parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

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

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

    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.MetricValue getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface RegistryOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.shared.Registry)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>repeated .exec.shared.Jar jar = 1;</code>
     */
    java.util.List<org.apache.drill.exec.proto.UserBitShared.Jar> 
        getJarList();
    /**
     * <code>repeated .exec.shared.Jar jar = 1;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.Jar getJar(int index);
    /**
     * <code>repeated .exec.shared.Jar jar = 1;</code>
     */
    int getJarCount();
    /**
     * <code>repeated .exec.shared.Jar jar = 1;</code>
     */
    java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.JarOrBuilder> 
        getJarOrBuilderList();
    /**
     * <code>repeated .exec.shared.Jar jar = 1;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.JarOrBuilder getJarOrBuilder(
        int index);
  }
  /**
   * <pre>
   * Registry that contains list of jars, each jar contains its name and list of function signatures.
   *Structure example:
   *REGISTRY    -&gt; Jar1.jar   -&gt; upper(VARCHAR-REQUIRED)
   *-&gt; upper(VARCHAR-OPTIONAL)
   *-&gt; Jar2.jar   -&gt; lower(VARCHAR-REQUIRED)
   *-&gt; lower(VARCHAR-OPTIONAL)
   * </pre>
   *
   * Protobuf type {@code exec.shared.Registry}
   */
  public static final class Registry extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.Registry)
      RegistryOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use Registry.newBuilder() to construct.
    private Registry(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private Registry() {
      jar_ = java.util.Collections.emptyList();
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new Registry();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_Registry_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_Registry_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserBitShared.Registry.class, org.apache.drill.exec.proto.UserBitShared.Registry.Builder.class);
    }

    public static final int JAR_FIELD_NUMBER = 1;
    private java.util.List<org.apache.drill.exec.proto.UserBitShared.Jar> jar_;
    /**
     * <code>repeated .exec.shared.Jar jar = 1;</code>
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.UserBitShared.Jar> getJarList() {
      return jar_;
    }
    /**
     * <code>repeated .exec.shared.Jar jar = 1;</code>
     */
    @java.lang.Override
    public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.JarOrBuilder> 
        getJarOrBuilderList() {
      return jar_;
    }
    /**
     * <code>repeated .exec.shared.Jar jar = 1;</code>
     */
    @java.lang.Override
    public int getJarCount() {
      return jar_.size();
    }
    /**
     * <code>repeated .exec.shared.Jar jar = 1;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.Jar getJar(int index) {
      return jar_.get(index);
    }
    /**
     * <code>repeated .exec.shared.Jar jar = 1;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.JarOrBuilder getJarOrBuilder(
        int index) {
      return jar_.get(index);
    }

    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 < jar_.size(); i++) {
        output.writeMessage(1, jar_.get(i));
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      for (int i = 0; i < jar_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, jar_.get(i));
      }
      size += getUnknownFields().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.drill.exec.proto.UserBitShared.Registry)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserBitShared.Registry other = (org.apache.drill.exec.proto.UserBitShared.Registry) obj;

      if (!getJarList()
          .equals(other.getJarList())) return false;
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (getJarCount() > 0) {
        hash = (37 * hash) + JAR_FIELD_NUMBER;
        hash = (53 * hash) + getJarList().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserBitShared.Registry parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.Registry parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.Registry parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.Registry 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.drill.exec.proto.UserBitShared.Registry parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.Registry parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.Registry parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.Registry 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.drill.exec.proto.UserBitShared.Registry parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.Registry 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.drill.exec.proto.UserBitShared.Registry parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.Registry 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.drill.exec.proto.UserBitShared.Registry 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>
     * Registry that contains list of jars, each jar contains its name and list of function signatures.
     *Structure example:
     *REGISTRY    -&gt; Jar1.jar   -&gt; upper(VARCHAR-REQUIRED)
     *-&gt; upper(VARCHAR-OPTIONAL)
     *-&gt; Jar2.jar   -&gt; lower(VARCHAR-REQUIRED)
     *-&gt; lower(VARCHAR-OPTIONAL)
     * </pre>
     *
     * Protobuf type {@code exec.shared.Registry}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.shared.Registry)
        org.apache.drill.exec.proto.UserBitShared.RegistryOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_Registry_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_Registry_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserBitShared.Registry.class, org.apache.drill.exec.proto.UserBitShared.Registry.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserBitShared.Registry.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        if (jarBuilder_ == null) {
          jar_ = java.util.Collections.emptyList();
        } else {
          jar_ = null;
          jarBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_Registry_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.Registry getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserBitShared.Registry.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.Registry build() {
        org.apache.drill.exec.proto.UserBitShared.Registry result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.Registry buildPartial() {
        org.apache.drill.exec.proto.UserBitShared.Registry result = new org.apache.drill.exec.proto.UserBitShared.Registry(this);
        int from_bitField0_ = bitField0_;
        if (jarBuilder_ == null) {
          if (((bitField0_ & 0x00000001) != 0)) {
            jar_ = java.util.Collections.unmodifiableList(jar_);
            bitField0_ = (bitField0_ & ~0x00000001);
          }
          result.jar_ = jar_;
        } else {
          result.jar_ = jarBuilder_.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.drill.exec.proto.UserBitShared.Registry) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.Registry)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.Registry other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.Registry.getDefaultInstance()) return this;
        if (jarBuilder_ == null) {
          if (!other.jar_.isEmpty()) {
            if (jar_.isEmpty()) {
              jar_ = other.jar_;
              bitField0_ = (bitField0_ & ~0x00000001);
            } else {
              ensureJarIsMutable();
              jar_.addAll(other.jar_);
            }
            onChanged();
          }
        } else {
          if (!other.jar_.isEmpty()) {
            if (jarBuilder_.isEmpty()) {
              jarBuilder_.dispose();
              jarBuilder_ = null;
              jar_ = other.jar_;
              bitField0_ = (bitField0_ & ~0x00000001);
              jarBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getJarFieldBuilder() : null;
            } else {
              jarBuilder_.addAllMessages(other.jar_);
            }
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        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 {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                org.apache.drill.exec.proto.UserBitShared.Jar m =
                    input.readMessage(
                        org.apache.drill.exec.proto.UserBitShared.Jar.PARSER,
                        extensionRegistry);
                if (jarBuilder_ == null) {
                  ensureJarIsMutable();
                  jar_.add(m);
                } else {
                  jarBuilder_.addMessage(m);
                }
                break;
              } // case 10
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.util.List<org.apache.drill.exec.proto.UserBitShared.Jar> jar_ =
        java.util.Collections.emptyList();
      private void ensureJarIsMutable() {
        if (!((bitField0_ & 0x00000001) != 0)) {
          jar_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserBitShared.Jar>(jar_);
          bitField0_ |= 0x00000001;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.Jar, org.apache.drill.exec.proto.UserBitShared.Jar.Builder, org.apache.drill.exec.proto.UserBitShared.JarOrBuilder> jarBuilder_;

      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserBitShared.Jar> getJarList() {
        if (jarBuilder_ == null) {
          return java.util.Collections.unmodifiableList(jar_);
        } else {
          return jarBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public int getJarCount() {
        if (jarBuilder_ == null) {
          return jar_.size();
        } else {
          return jarBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.Jar getJar(int index) {
        if (jarBuilder_ == null) {
          return jar_.get(index);
        } else {
          return jarBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public Builder setJar(
          int index, org.apache.drill.exec.proto.UserBitShared.Jar value) {
        if (jarBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureJarIsMutable();
          jar_.set(index, value);
          onChanged();
        } else {
          jarBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public Builder setJar(
          int index, org.apache.drill.exec.proto.UserBitShared.Jar.Builder builderForValue) {
        if (jarBuilder_ == null) {
          ensureJarIsMutable();
          jar_.set(index, builderForValue.build());
          onChanged();
        } else {
          jarBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public Builder addJar(org.apache.drill.exec.proto.UserBitShared.Jar value) {
        if (jarBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureJarIsMutable();
          jar_.add(value);
          onChanged();
        } else {
          jarBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public Builder addJar(
          int index, org.apache.drill.exec.proto.UserBitShared.Jar value) {
        if (jarBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureJarIsMutable();
          jar_.add(index, value);
          onChanged();
        } else {
          jarBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public Builder addJar(
          org.apache.drill.exec.proto.UserBitShared.Jar.Builder builderForValue) {
        if (jarBuilder_ == null) {
          ensureJarIsMutable();
          jar_.add(builderForValue.build());
          onChanged();
        } else {
          jarBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public Builder addJar(
          int index, org.apache.drill.exec.proto.UserBitShared.Jar.Builder builderForValue) {
        if (jarBuilder_ == null) {
          ensureJarIsMutable();
          jar_.add(index, builderForValue.build());
          onChanged();
        } else {
          jarBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public Builder addAllJar(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.UserBitShared.Jar> values) {
        if (jarBuilder_ == null) {
          ensureJarIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, jar_);
          onChanged();
        } else {
          jarBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public Builder clearJar() {
        if (jarBuilder_ == null) {
          jar_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
          onChanged();
        } else {
          jarBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public Builder removeJar(int index) {
        if (jarBuilder_ == null) {
          ensureJarIsMutable();
          jar_.remove(index);
          onChanged();
        } else {
          jarBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.Jar.Builder getJarBuilder(
          int index) {
        return getJarFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.JarOrBuilder getJarOrBuilder(
          int index) {
        if (jarBuilder_ == null) {
          return jar_.get(index);  } else {
          return jarBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.JarOrBuilder> 
           getJarOrBuilderList() {
        if (jarBuilder_ != null) {
          return jarBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(jar_);
        }
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.Jar.Builder addJarBuilder() {
        return getJarFieldBuilder().addBuilder(
            org.apache.drill.exec.proto.UserBitShared.Jar.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.Jar.Builder addJarBuilder(
          int index) {
        return getJarFieldBuilder().addBuilder(
            index, org.apache.drill.exec.proto.UserBitShared.Jar.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserBitShared.Jar.Builder> 
           getJarBuilderList() {
        return getJarFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.Jar, org.apache.drill.exec.proto.UserBitShared.Jar.Builder, org.apache.drill.exec.proto.UserBitShared.JarOrBuilder> 
          getJarFieldBuilder() {
        if (jarBuilder_ == null) {
          jarBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.Jar, org.apache.drill.exec.proto.UserBitShared.Jar.Builder, org.apache.drill.exec.proto.UserBitShared.JarOrBuilder>(
                  jar_,
                  ((bitField0_ & 0x00000001) != 0),
                  getParentForChildren(),
                  isClean());
          jar_ = null;
        }
        return jarBuilder_;
      }
      @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:exec.shared.Registry)
    }

    // @@protoc_insertion_point(class_scope:exec.shared.Registry)
    private static final org.apache.drill.exec.proto.UserBitShared.Registry DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserBitShared.Registry();
    }

    public static org.apache.drill.exec.proto.UserBitShared.Registry getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<Registry>
        PARSER = new com.google.protobuf.AbstractParser<Registry>() {
      @java.lang.Override
      public Registry parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

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

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

    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.Registry getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface JarOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.shared.Jar)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional string name = 1;</code>
     * @return Whether the name field is set.
     */
    boolean hasName();
    /**
     * <code>optional string name = 1;</code>
     * @return The name.
     */
    java.lang.String getName();
    /**
     * <code>optional string name = 1;</code>
     * @return The bytes for name.
     */
    com.google.protobuf.ByteString
        getNameBytes();

    /**
     * <code>repeated string function_signature = 2;</code>
     * @return A list containing the functionSignature.
     */
    java.util.List<java.lang.String>
        getFunctionSignatureList();
    /**
     * <code>repeated string function_signature = 2;</code>
     * @return The count of functionSignature.
     */
    int getFunctionSignatureCount();
    /**
     * <code>repeated string function_signature = 2;</code>
     * @param index The index of the element to return.
     * @return The functionSignature at the given index.
     */
    java.lang.String getFunctionSignature(int index);
    /**
     * <code>repeated string function_signature = 2;</code>
     * @param index The index of the value to return.
     * @return The bytes of the functionSignature at the given index.
     */
    com.google.protobuf.ByteString
        getFunctionSignatureBytes(int index);
  }
  /**
   * <pre>
   * Jar contains jar name and list of function signatures.
   *Function signature is concatenation of function name and its input parameters. 
   * </pre>
   *
   * Protobuf type {@code exec.shared.Jar}
   */
  public static final class Jar extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.Jar)
      JarOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use Jar.newBuilder() to construct.
    private Jar(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private Jar() {
      name_ = "";
      functionSignature_ = com.google.protobuf.LazyStringArrayList.EMPTY;
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new Jar();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_Jar_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_Jar_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserBitShared.Jar.class, org.apache.drill.exec.proto.UserBitShared.Jar.Builder.class);
    }

    private int bitField0_;
    public static final int NAME_FIELD_NUMBER = 1;
    private volatile java.lang.Object name_;
    /**
     * <code>optional string name = 1;</code>
     * @return Whether the name field is set.
     */
    @java.lang.Override
    public boolean hasName() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional string name = 1;</code>
     * @return The name.
     */
    @java.lang.Override
    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();
        if (bs.isValidUtf8()) {
          name_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string name = 1;</code>
     * @return The bytes for name.
     */
    @java.lang.Override
    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 FUNCTION_SIGNATURE_FIELD_NUMBER = 2;
    private com.google.protobuf.LazyStringList functionSignature_;
    /**
     * <code>repeated string function_signature = 2;</code>
     * @return A list containing the functionSignature.
     */
    public com.google.protobuf.ProtocolStringList
        getFunctionSignatureList() {
      return functionSignature_;
    }
    /**
     * <code>repeated string function_signature = 2;</code>
     * @return The count of functionSignature.
     */
    public int getFunctionSignatureCount() {
      return functionSignature_.size();
    }
    /**
     * <code>repeated string function_signature = 2;</code>
     * @param index The index of the element to return.
     * @return The functionSignature at the given index.
     */
    public java.lang.String getFunctionSignature(int index) {
      return functionSignature_.get(index);
    }
    /**
     * <code>repeated string function_signature = 2;</code>
     * @param index The index of the value to return.
     * @return The bytes of the functionSignature at the given index.
     */
    public com.google.protobuf.ByteString
        getFunctionSignatureBytes(int index) {
      return functionSignature_.getByteString(index);
    }

    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 (((bitField0_ & 0x00000001) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, name_);
      }
      for (int i = 0; i < functionSignature_.size(); i++) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, functionSignature_.getRaw(i));
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, name_);
      }
      {
        int dataSize = 0;
        for (int i = 0; i < functionSignature_.size(); i++) {
          dataSize += computeStringSizeNoTag(functionSignature_.getRaw(i));
        }
        size += dataSize;
        size += 1 * getFunctionSignatureList().size();
      }
      size += getUnknownFields().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.drill.exec.proto.UserBitShared.Jar)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserBitShared.Jar other = (org.apache.drill.exec.proto.UserBitShared.Jar) obj;

      if (hasName() != other.hasName()) return false;
      if (hasName()) {
        if (!getName()
            .equals(other.getName())) return false;
      }
      if (!getFunctionSignatureList()
          .equals(other.getFunctionSignatureList())) return false;
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasName()) {
        hash = (37 * hash) + NAME_FIELD_NUMBER;
        hash = (53 * hash) + getName().hashCode();
      }
      if (getFunctionSignatureCount() > 0) {
        hash = (37 * hash) + FUNCTION_SIGNATURE_FIELD_NUMBER;
        hash = (53 * hash) + getFunctionSignatureList().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserBitShared.Jar parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.Jar parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.Jar parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.Jar 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.drill.exec.proto.UserBitShared.Jar parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.Jar parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.Jar parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.Jar 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.drill.exec.proto.UserBitShared.Jar parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.Jar 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.drill.exec.proto.UserBitShared.Jar parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.Jar 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.drill.exec.proto.UserBitShared.Jar 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>
     * Jar contains jar name and list of function signatures.
     *Function signature is concatenation of function name and its input parameters. 
     * </pre>
     *
     * Protobuf type {@code exec.shared.Jar}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.shared.Jar)
        org.apache.drill.exec.proto.UserBitShared.JarOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_Jar_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_Jar_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserBitShared.Jar.class, org.apache.drill.exec.proto.UserBitShared.Jar.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserBitShared.Jar.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        name_ = "";
        bitField0_ = (bitField0_ & ~0x00000001);
        functionSignature_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_Jar_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.Jar getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserBitShared.Jar.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.Jar build() {
        org.apache.drill.exec.proto.UserBitShared.Jar result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.Jar buildPartial() {
        org.apache.drill.exec.proto.UserBitShared.Jar result = new org.apache.drill.exec.proto.UserBitShared.Jar(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.name_ = name_;
        if (((bitField0_ & 0x00000002) != 0)) {
          functionSignature_ = functionSignature_.getUnmodifiableView();
          bitField0_ = (bitField0_ & ~0x00000002);
        }
        result.functionSignature_ = functionSignature_;
        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.drill.exec.proto.UserBitShared.Jar) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.Jar)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.Jar other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.Jar.getDefaultInstance()) return this;
        if (other.hasName()) {
          bitField0_ |= 0x00000001;
          name_ = other.name_;
          onChanged();
        }
        if (!other.functionSignature_.isEmpty()) {
          if (functionSignature_.isEmpty()) {
            functionSignature_ = other.functionSignature_;
            bitField0_ = (bitField0_ & ~0x00000002);
          } else {
            ensureFunctionSignatureIsMutable();
            functionSignature_.addAll(other.functionSignature_);
          }
          onChanged();
        }
        this.mergeUnknownFields(other.getUnknownFields());
        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 {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                name_ = input.readBytes();
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 18: {
                com.google.protobuf.ByteString bs = input.readBytes();
                ensureFunctionSignatureIsMutable();
                functionSignature_.add(bs);
                break;
              } // case 18
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.lang.Object name_ = "";
      /**
       * <code>optional string name = 1;</code>
       * @return Whether the name field is set.
       */
      public boolean hasName() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional string name = 1;</code>
       * @return The name.
       */
      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();
          if (bs.isValidUtf8()) {
            name_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string name = 1;</code>
       * @return The bytes for name.
       */
      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>optional string name = 1;</code>
       * @param value The name to set.
       * @return This builder for chaining.
       */
      public Builder setName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        name_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string name = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearName() {
        bitField0_ = (bitField0_ & ~0x00000001);
        name_ = getDefaultInstance().getName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string name = 1;</code>
       * @param value The bytes for name to set.
       * @return This builder for chaining.
       */
      public Builder setNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        name_ = value;
        onChanged();
        return this;
      }

      private com.google.protobuf.LazyStringList functionSignature_ = com.google.protobuf.LazyStringArrayList.EMPTY;
      private void ensureFunctionSignatureIsMutable() {
        if (!((bitField0_ & 0x00000002) != 0)) {
          functionSignature_ = new com.google.protobuf.LazyStringArrayList(functionSignature_);
          bitField0_ |= 0x00000002;
         }
      }
      /**
       * <code>repeated string function_signature = 2;</code>
       * @return A list containing the functionSignature.
       */
      public com.google.protobuf.ProtocolStringList
          getFunctionSignatureList() {
        return functionSignature_.getUnmodifiableView();
      }
      /**
       * <code>repeated string function_signature = 2;</code>
       * @return The count of functionSignature.
       */
      public int getFunctionSignatureCount() {
        return functionSignature_.size();
      }
      /**
       * <code>repeated string function_signature = 2;</code>
       * @param index The index of the element to return.
       * @return The functionSignature at the given index.
       */
      public java.lang.String getFunctionSignature(int index) {
        return functionSignature_.get(index);
      }
      /**
       * <code>repeated string function_signature = 2;</code>
       * @param index The index of the value to return.
       * @return The bytes of the functionSignature at the given index.
       */
      public com.google.protobuf.ByteString
          getFunctionSignatureBytes(int index) {
        return functionSignature_.getByteString(index);
      }
      /**
       * <code>repeated string function_signature = 2;</code>
       * @param index The index to set the value at.
       * @param value The functionSignature to set.
       * @return This builder for chaining.
       */
      public Builder setFunctionSignature(
          int index, java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureFunctionSignatureIsMutable();
        functionSignature_.set(index, value);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string function_signature = 2;</code>
       * @param value The functionSignature to add.
       * @return This builder for chaining.
       */
      public Builder addFunctionSignature(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureFunctionSignatureIsMutable();
        functionSignature_.add(value);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string function_signature = 2;</code>
       * @param values The functionSignature to add.
       * @return This builder for chaining.
       */
      public Builder addAllFunctionSignature(
          java.lang.Iterable<java.lang.String> values) {
        ensureFunctionSignatureIsMutable();
        com.google.protobuf.AbstractMessageLite.Builder.addAll(
            values, functionSignature_);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string function_signature = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearFunctionSignature() {
        functionSignature_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000002);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string function_signature = 2;</code>
       * @param value The bytes of the functionSignature to add.
       * @return This builder for chaining.
       */
      public Builder addFunctionSignatureBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureFunctionSignatureIsMutable();
        functionSignature_.add(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:exec.shared.Jar)
    }

    // @@protoc_insertion_point(class_scope:exec.shared.Jar)
    private static final org.apache.drill.exec.proto.UserBitShared.Jar DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserBitShared.Jar();
    }

    public static org.apache.drill.exec.proto.UserBitShared.Jar getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<Jar>
        PARSER = new com.google.protobuf.AbstractParser<Jar>() {
      @java.lang.Override
      public Jar parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

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

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

    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.Jar getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface SaslMessageOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.shared.SaslMessage)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional string mechanism = 1;</code>
     * @return Whether the mechanism field is set.
     */
    boolean hasMechanism();
    /**
     * <code>optional string mechanism = 1;</code>
     * @return The mechanism.
     */
    java.lang.String getMechanism();
    /**
     * <code>optional string mechanism = 1;</code>
     * @return The bytes for mechanism.
     */
    com.google.protobuf.ByteString
        getMechanismBytes();

    /**
     * <code>optional bytes data = 2;</code>
     * @return Whether the data field is set.
     */
    boolean hasData();
    /**
     * <code>optional bytes data = 2;</code>
     * @return The data.
     */
    com.google.protobuf.ByteString getData();

    /**
     * <code>optional .exec.shared.SaslStatus status = 3;</code>
     * @return Whether the status field is set.
     */
    boolean hasStatus();
    /**
     * <code>optional .exec.shared.SaslStatus status = 3;</code>
     * @return The status.
     */
    org.apache.drill.exec.proto.UserBitShared.SaslStatus getStatus();
  }
  /**
   * Protobuf type {@code exec.shared.SaslMessage}
   */
  public static final class SaslMessage extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.SaslMessage)
      SaslMessageOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use SaslMessage.newBuilder() to construct.
    private SaslMessage(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private SaslMessage() {
      mechanism_ = "";
      data_ = com.google.protobuf.ByteString.EMPTY;
      status_ = 0;
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new SaslMessage();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_SaslMessage_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_SaslMessage_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserBitShared.SaslMessage.class, org.apache.drill.exec.proto.UserBitShared.SaslMessage.Builder.class);
    }

    private int bitField0_;
    public static final int MECHANISM_FIELD_NUMBER = 1;
    private volatile java.lang.Object mechanism_;
    /**
     * <code>optional string mechanism = 1;</code>
     * @return Whether the mechanism field is set.
     */
    @java.lang.Override
    public boolean hasMechanism() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional string mechanism = 1;</code>
     * @return The mechanism.
     */
    @java.lang.Override
    public java.lang.String getMechanism() {
      java.lang.Object ref = mechanism_;
      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();
        if (bs.isValidUtf8()) {
          mechanism_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string mechanism = 1;</code>
     * @return The bytes for mechanism.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getMechanismBytes() {
      java.lang.Object ref = mechanism_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        mechanism_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int DATA_FIELD_NUMBER = 2;
    private com.google.protobuf.ByteString data_;
    /**
     * <code>optional bytes data = 2;</code>
     * @return Whether the data field is set.
     */
    @java.lang.Override
    public boolean hasData() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional bytes data = 2;</code>
     * @return The data.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString getData() {
      return data_;
    }

    public static final int STATUS_FIELD_NUMBER = 3;
    private int status_;
    /**
     * <code>optional .exec.shared.SaslStatus status = 3;</code>
     * @return Whether the status field is set.
     */
    @java.lang.Override public boolean hasStatus() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional .exec.shared.SaslStatus status = 3;</code>
     * @return The status.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserBitShared.SaslStatus getStatus() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserBitShared.SaslStatus result = org.apache.drill.exec.proto.UserBitShared.SaslStatus.valueOf(status_);
      return result == null ? org.apache.drill.exec.proto.UserBitShared.SaslStatus.SASL_UNKNOWN : result;
    }

    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 (((bitField0_ & 0x00000001) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, mechanism_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeBytes(2, data_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeEnum(3, status_);
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, mechanism_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(2, data_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(3, status_);
      }
      size += getUnknownFields().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.drill.exec.proto.UserBitShared.SaslMessage)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserBitShared.SaslMessage other = (org.apache.drill.exec.proto.UserBitShared.SaslMessage) obj;

      if (hasMechanism() != other.hasMechanism()) return false;
      if (hasMechanism()) {
        if (!getMechanism()
            .equals(other.getMechanism())) return false;
      }
      if (hasData() != other.hasData()) return false;
      if (hasData()) {
        if (!getData()
            .equals(other.getData())) return false;
      }
      if (hasStatus() != other.hasStatus()) return false;
      if (hasStatus()) {
        if (status_ != other.status_) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasMechanism()) {
        hash = (37 * hash) + MECHANISM_FIELD_NUMBER;
        hash = (53 * hash) + getMechanism().hashCode();
      }
      if (hasData()) {
        hash = (37 * hash) + DATA_FIELD_NUMBER;
        hash = (53 * hash) + getData().hashCode();
      }
      if (hasStatus()) {
        hash = (37 * hash) + STATUS_FIELD_NUMBER;
        hash = (53 * hash) + status_;
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserBitShared.SaslMessage parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.SaslMessage parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.SaslMessage parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.SaslMessage 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.drill.exec.proto.UserBitShared.SaslMessage parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserBitShared.SaslMessage parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserBitShared.SaslMessage parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.SaslMessage 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.drill.exec.proto.UserBitShared.SaslMessage parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.SaslMessage 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.drill.exec.proto.UserBitShared.SaslMessage parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserBitShared.SaslMessage 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.drill.exec.proto.UserBitShared.SaslMessage 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 exec.shared.SaslMessage}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.shared.SaslMessage)
        org.apache.drill.exec.proto.UserBitShared.SaslMessageOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_SaslMessage_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_SaslMessage_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserBitShared.SaslMessage.class, org.apache.drill.exec.proto.UserBitShared.SaslMessage.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserBitShared.SaslMessage.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        mechanism_ = "";
        bitField0_ = (bitField0_ & ~0x00000001);
        data_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000002);
        status_ = 0;
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserBitShared.internal_static_exec_shared_SaslMessage_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.SaslMessage getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserBitShared.SaslMessage.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.SaslMessage build() {
        org.apache.drill.exec.proto.UserBitShared.SaslMessage result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.SaslMessage buildPartial() {
        org.apache.drill.exec.proto.UserBitShared.SaslMessage result = new org.apache.drill.exec.proto.UserBitShared.SaslMessage(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.mechanism_ = mechanism_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          to_bitField0_ |= 0x00000002;
        }
        result.data_ = data_;
        if (((from_bitField0_ & 0x00000004) != 0)) {
          to_bitField0_ |= 0x00000004;
        }
        result.status_ = status_;
        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.drill.exec.proto.UserBitShared.SaslMessage) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.SaslMessage)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.SaslMessage other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.SaslMessage.getDefaultInstance()) return this;
        if (other.hasMechanism()) {
          bitField0_ |= 0x00000001;
          mechanism_ = other.mechanism_;
          onChanged();
        }
        if (other.hasData()) {
          setData(other.getData());
        }
        if (other.hasStatus()) {
          setStatus(other.getStatus());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        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 {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                mechanism_ = input.readBytes();
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 18: {
                data_ = input.readBytes();
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              case 24: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserBitShared.SaslStatus tmpValue =
                    org.apache.drill.exec.proto.UserBitShared.SaslStatus.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(3, tmpRaw);
                } else {
                  status_ = tmpRaw;
                  bitField0_ |= 0x00000004;
                }
                break;
              } // case 24
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.lang.Object mechanism_ = "";
      /**
       * <code>optional string mechanism = 1;</code>
       * @return Whether the mechanism field is set.
       */
      public boolean hasMechanism() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional string mechanism = 1;</code>
       * @return The mechanism.
       */
      public java.lang.String getMechanism() {
        java.lang.Object ref = mechanism_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            mechanism_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string mechanism = 1;</code>
       * @return The bytes for mechanism.
       */
      public com.google.protobuf.ByteString
          getMechanismBytes() {
        java.lang.Object ref = mechanism_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          mechanism_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string mechanism = 1;</code>
       * @param value The mechanism to set.
       * @return This builder for chaining.
       */
      public Builder setMechanism(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        mechanism_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string mechanism = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearMechanism() {
        bitField0_ = (bitField0_ & ~0x00000001);
        mechanism_ = getDefaultInstance().getMechanism();
        onChanged();
        return this;
      }
      /**
       * <code>optional string mechanism = 1;</code>
       * @param value The bytes for mechanism to set.
       * @return This builder for chaining.
       */
      public Builder setMechanismBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        mechanism_ = value;
        onChanged();
        return this;
      }

      private com.google.protobuf.ByteString data_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>optional bytes data = 2;</code>
       * @return Whether the data field is set.
       */
      @java.lang.Override
      public boolean hasData() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional bytes data = 2;</code>
       * @return The data.
       */
      @java.lang.Override
      public com.google.protobuf.ByteString getData() {
        return data_;
      }
      /**
       * <code>optional bytes data = 2;</code>
       * @param value The data to set.
       * @return This builder for chaining.
       */
      public Builder setData(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        data_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bytes data = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearData() {
        bitField0_ = (bitField0_ & ~0x00000002);
        data_ = getDefaultInstance().getData();
        onChanged();
        return this;
      }

      private int status_ = 0;
      /**
       * <code>optional .exec.shared.SaslStatus status = 3;</code>
       * @return Whether the status field is set.
       */
      @java.lang.Override public boolean hasStatus() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional .exec.shared.SaslStatus status = 3;</code>
       * @return The status.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.SaslStatus getStatus() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserBitShared.SaslStatus result = org.apache.drill.exec.proto.UserBitShared.SaslStatus.valueOf(status_);
        return result == null ? org.apache.drill.exec.proto.UserBitShared.SaslStatus.SASL_UNKNOWN : result;
      }
      /**
       * <code>optional .exec.shared.SaslStatus status = 3;</code>
       * @param value The status to set.
       * @return This builder for chaining.
       */
      public Builder setStatus(org.apache.drill.exec.proto.UserBitShared.SaslStatus value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000004;
        status_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .exec.shared.SaslStatus status = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearStatus() {
        bitField0_ = (bitField0_ & ~0x00000004);
        status_ = 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:exec.shared.SaslMessage)
    }

    // @@protoc_insertion_point(class_scope:exec.shared.SaslMessage)
    private static final org.apache.drill.exec.proto.UserBitShared.SaslMessage DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserBitShared.SaslMessage();
    }

    public static org.apache.drill.exec.proto.UserBitShared.SaslMessage getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<SaslMessage>
        PARSER = new com.google.protobuf.AbstractParser<SaslMessage>() {
      @java.lang.Override
      public SaslMessage parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

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

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

    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.SaslMessage getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_shared_UserCredentials_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_shared_UserCredentials_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_shared_QueryId_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_shared_QueryId_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_shared_DrillPBError_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_shared_DrillPBError_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_shared_ExceptionWrapper_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_shared_ExceptionWrapper_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_shared_StackTraceElementWrapper_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_shared_StackTraceElementWrapper_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_shared_ParsingError_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_shared_ParsingError_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_shared_RecordBatchDef_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_shared_RecordBatchDef_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_shared_NamePart_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_shared_NamePart_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_shared_SerializedField_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_shared_SerializedField_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_shared_NodeStatus_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_shared_NodeStatus_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_shared_QueryResult_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_shared_QueryResult_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_shared_QueryData_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_shared_QueryData_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_shared_QueryInfo_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_shared_QueryInfo_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_shared_QueryProfile_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_shared_QueryProfile_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_shared_MajorFragmentProfile_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_shared_MajorFragmentProfile_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_shared_MinorFragmentProfile_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_shared_MinorFragmentProfile_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_shared_OperatorProfile_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_shared_OperatorProfile_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_shared_StreamProfile_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_shared_StreamProfile_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_shared_MetricValue_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_shared_MetricValue_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_shared_Registry_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_shared_Registry_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_shared_Jar_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_shared_Jar_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_shared_SaslMessage_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_shared_SaslMessage_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\023UserBitShared.proto\022\013exec.shared\032\013Type" +
      "s.proto\032\022Coordination.proto\032\017SchemaDef.p" +
      "roto\"$\n\017UserCredentials\022\021\n\tuser_name\030\001 \001" +
      "(\t\"\'\n\007QueryId\022\r\n\005part1\030\001 \001(\020\022\r\n\005part2\030\002 " +
      "\001(\020\"\371\003\n\014DrillPBError\022\020\n\010error_id\030\001 \001(\t\022(" +
      "\n\010endpoint\030\002 \001(\0132\026.exec.DrillbitEndpoint" +
      "\0227\n\nerror_type\030\003 \001(\0162#.exec.shared.Drill" +
      "PBError.ErrorType\022\017\n\007message\030\004 \001(\t\0220\n\tex" +
      "ception\030\005 \001(\0132\035.exec.shared.ExceptionWra" +
      "pper\0220\n\rparsing_error\030\006 \003(\0132\031.exec.share" +
      "d.ParsingError\"\376\001\n\tErrorType\022\016\n\nCONNECTI" +
      "ON\020\000\022\r\n\tDATA_READ\020\001\022\016\n\nDATA_WRITE\020\002\022\014\n\010F" +
      "UNCTION\020\003\022\t\n\005PARSE\020\004\022\016\n\nPERMISSION\020\005\022\010\n\004" +
      "PLAN\020\006\022\014\n\010RESOURCE\020\007\022\n\n\006SYSTEM\020\010\022\031\n\025UNSU" +
      "PPORTED_OPERATION\020\t\022\016\n\nVALIDATION\020\n\022\023\n\017E" +
      "XECUTION_ERROR\020\013\022\022\n\016INTERNAL_ERROR\020\014\022\025\n\021" +
      "UNSPECIFIED_ERROR\020\r\022\n\n\006PLUGIN\020\016\"\246\001\n\020Exce" +
      "ptionWrapper\022\027\n\017exception_class\030\001 \001(\t\022\017\n" +
      "\007message\030\002 \001(\t\022:\n\013stack_trace\030\003 \003(\0132%.ex" +
      "ec.shared.StackTraceElementWrapper\022,\n\005ca" +
      "use\030\004 \001(\0132\035.exec.shared.ExceptionWrapper" +
      "\"\205\001\n\030StackTraceElementWrapper\022\022\n\nclass_n" +
      "ame\030\001 \001(\t\022\021\n\tfile_name\030\002 \001(\t\022\023\n\013line_num" +
      "ber\030\003 \001(\005\022\023\n\013method_name\030\004 \001(\t\022\030\n\020is_nat" +
      "ive_method\030\005 \001(\010\"\\\n\014ParsingError\022\024\n\014star" +
      "t_column\030\002 \001(\005\022\021\n\tstart_row\030\003 \001(\005\022\022\n\nend" +
      "_column\030\004 \001(\005\022\017\n\007end_row\030\005 \001(\005\"\233\001\n\016Recor" +
      "dBatchDef\022\024\n\014record_count\030\001 \001(\005\022+\n\005field" +
      "\030\002 \003(\0132\034.exec.shared.SerializedField\022)\n!" +
      "carries_two_byte_selection_vector\030\003 \001(\010\022" +
      "\033\n\023affected_rows_count\030\004 \001(\005\"\205\001\n\010NamePar" +
      "t\022(\n\004type\030\001 \001(\0162\032.exec.shared.NamePart.T" +
      "ype\022\014\n\004name\030\002 \001(\t\022$\n\005child\030\003 \001(\0132\025.exec." +
      "shared.NamePart\"\033\n\004Type\022\010\n\004NAME\020\000\022\t\n\005ARR" +
      "AY\020\001\"\324\001\n\017SerializedField\022%\n\nmajor_type\030\001" +
      " \001(\0132\021.common.MajorType\022(\n\tname_part\030\002 \001" +
      "(\0132\025.exec.shared.NamePart\022+\n\005child\030\003 \003(\013" +
      "2\034.exec.shared.SerializedField\022\023\n\013value_" +
      "count\030\004 \001(\005\022\027\n\017var_byte_length\030\005 \001(\005\022\025\n\r" +
      "buffer_length\030\007 \001(\005\"7\n\nNodeStatus\022\017\n\007nod" +
      "e_id\030\001 \001(\005\022\030\n\020memory_footprint\030\002 \001(\003\"\263\002\n" +
      "\013QueryResult\0228\n\013query_state\030\001 \001(\0162#.exec" +
      ".shared.QueryResult.QueryState\022&\n\010query_" +
      "id\030\002 \001(\0132\024.exec.shared.QueryId\022(\n\005error\030" +
      "\003 \003(\0132\031.exec.shared.DrillPBError\"\227\001\n\nQue" +
      "ryState\022\014\n\010STARTING\020\000\022\013\n\007RUNNING\020\001\022\r\n\tCO" +
      "MPLETED\020\002\022\014\n\010CANCELED\020\003\022\n\n\006FAILED\020\004\022\032\n\026C" +
      "ANCELLATION_REQUESTED\020\005\022\014\n\010ENQUEUED\020\006\022\r\n" +
      "\tPREPARING\020\007\022\014\n\010PLANNING\020\010\"\215\001\n\tQueryData" +
      "\022&\n\010query_id\030\001 \001(\0132\024.exec.shared.QueryId" +
      "\022\021\n\trow_count\030\002 \001(\005\022(\n\003def\030\003 \001(\0132\033.exec." +
      "shared.RecordBatchDef\022\033\n\023affected_rows_c" +
      "ount\030\004 \001(\005\"\330\001\n\tQueryInfo\022\r\n\005query\030\001 \001(\t\022" +
      "\r\n\005start\030\002 \001(\003\0222\n\005state\030\003 \001(\0162#.exec.sha" +
      "red.QueryResult.QueryState\022\017\n\004user\030\004 \001(\t" +
      ":\001-\022\'\n\007foreman\030\005 \001(\0132\026.exec.DrillbitEndp" +
      "oint\022\024\n\014options_json\030\006 \001(\t\022\022\n\ntotal_cost" +
      "\030\007 \001(\001\022\025\n\nqueue_name\030\010 \001(\t:\001-\"\337\004\n\014QueryP" +
      "rofile\022 \n\002id\030\001 \001(\0132\024.exec.shared.QueryId" +
      "\022$\n\004type\030\002 \001(\0162\026.exec.shared.QueryType\022\r" +
      "\n\005start\030\003 \001(\003\022\013\n\003end\030\004 \001(\003\022\r\n\005query\030\005 \001(" +
      "\t\022\014\n\004plan\030\006 \001(\t\022\'\n\007foreman\030\007 \001(\0132\026.exec." +
      "DrillbitEndpoint\0222\n\005state\030\010 \001(\0162#.exec.s" +
      "hared.QueryResult.QueryState\022\027\n\017total_fr" +
      "agments\030\t \001(\005\022\032\n\022finished_fragments\030\n \001(" +
      "\005\022;\n\020fragment_profile\030\013 \003(\0132!.exec.share" +
      "d.MajorFragmentProfile\022\017\n\004user\030\014 \001(\t:\001-\022" +
      "\r\n\005error\030\r \001(\t\022\024\n\014verboseError\030\016 \001(\t\022\020\n\010" +
      "error_id\030\017 \001(\t\022\022\n\nerror_node\030\020 \001(\t\022\024\n\014op" +
      "tions_json\030\021 \001(\t\022\017\n\007planEnd\030\022 \001(\003\022\024\n\014que" +
      "ueWaitEnd\030\023 \001(\003\022\022\n\ntotal_cost\030\024 \001(\001\022\025\n\nq" +
      "ueue_name\030\025 \001(\t:\001-\022\017\n\007queryId\030\026 \001(\t\022\021\n\ta" +
      "utoLimit\030\027 \001(\005\022\027\n\017scanned_plugins\030\030 \003(\t\"" +
      "t\n\024MajorFragmentProfile\022\031\n\021major_fragmen" +
      "t_id\030\001 \001(\005\022A\n\026minor_fragment_profile\030\002 \003" +
      "(\0132!.exec.shared.MinorFragmentProfile\"\350\002" +
      "\n\024MinorFragmentProfile\022)\n\005state\030\001 \001(\0162\032." +
      "exec.shared.FragmentState\022(\n\005error\030\002 \001(\013" +
      "2\031.exec.shared.DrillPBError\022\031\n\021minor_fra" +
      "gment_id\030\003 \001(\005\0226\n\020operator_profile\030\004 \003(\013" +
      "2\034.exec.shared.OperatorProfile\022\022\n\nstart_" +
      "time\030\005 \001(\003\022\020\n\010end_time\030\006 \001(\003\022\023\n\013memory_u" +
      "sed\030\007 \001(\003\022\027\n\017max_memory_used\030\010 \001(\003\022(\n\010en" +
      "dpoint\030\t \001(\0132\026.exec.DrillbitEndpoint\022\023\n\013" +
      "last_update\030\n \001(\003\022\025\n\rlast_progress\030\013 \001(\003" +
      "\"\237\002\n\017OperatorProfile\0221\n\rinput_profile\030\001 " +
      "\003(\0132\032.exec.shared.StreamProfile\022\023\n\013opera" +
      "tor_id\030\003 \001(\005\022\031\n\roperator_type\030\004 \001(\005B\002\030\001\022" +
      "\023\n\013setup_nanos\030\005 \001(\003\022\025\n\rprocess_nanos\030\006 " +
      "\001(\003\022#\n\033peak_local_memory_allocated\030\007 \001(\003" +
      "\022(\n\006metric\030\010 \003(\0132\030.exec.shared.MetricVal" +
      "ue\022\022\n\nwait_nanos\030\t \001(\003\022\032\n\022operator_type_" +
      "name\030\n \001(\t\"B\n\rStreamProfile\022\017\n\007records\030\001" +
      " \001(\003\022\017\n\007batches\030\002 \001(\003\022\017\n\007schemas\030\003 \001(\003\"J" +
      "\n\013MetricValue\022\021\n\tmetric_id\030\001 \001(\005\022\022\n\nlong" +
      "_value\030\002 \001(\003\022\024\n\014double_value\030\003 \001(\001\")\n\010Re" +
      "gistry\022\035\n\003jar\030\001 \003(\0132\020.exec.shared.Jar\"/\n" +
      "\003Jar\022\014\n\004name\030\001 \001(\t\022\032\n\022function_signature" +
      "\030\002 \003(\t\"W\n\013SaslMessage\022\021\n\tmechanism\030\001 \001(\t" +
      "\022\014\n\004data\030\002 \001(\014\022\'\n\006status\030\003 \001(\0162\027.exec.sh" +
      "ared.SaslStatus*5\n\nRpcChannel\022\017\n\013BIT_CON" +
      "TROL\020\000\022\014\n\010BIT_DATA\020\001\022\010\n\004USER\020\002*V\n\tQueryT" +
      "ype\022\007\n\003SQL\020\001\022\013\n\007LOGICAL\020\002\022\014\n\010PHYSICAL\020\003\022" +
      "\r\n\tEXECUTION\020\004\022\026\n\022PREPARED_STATEMENT\020\005*\207" +
      "\001\n\rFragmentState\022\013\n\007SENDING\020\000\022\027\n\023AWAITIN" +
      "G_ALLOCATION\020\001\022\013\n\007RUNNING\020\002\022\014\n\010FINISHED\020" +
      "\003\022\r\n\tCANCELLED\020\004\022\n\n\006FAILED\020\005\022\032\n\026CANCELLA" +
      "TION_REQUESTED\020\006*g\n\nSaslStatus\022\020\n\014SASL_U" +
      "NKNOWN\020\000\022\016\n\nSASL_START\020\001\022\024\n\020SASL_IN_PROG" +
      "RESS\020\002\022\020\n\014SASL_SUCCESS\020\003\022\017\n\013SASL_FAILED\020" +
      "\004B.\n\033org.apache.drill.exec.protoB\rUserBi" +
      "tSharedH\001"
    };
    descriptor = com.google.protobuf.Descriptors.FileDescriptor
      .internalBuildGeneratedFileFrom(descriptorData,
        new com.google.protobuf.Descriptors.FileDescriptor[] {
          org.apache.drill.common.types.TypeProtos.getDescriptor(),
          org.apache.drill.exec.proto.CoordinationProtos.getDescriptor(),
          org.apache.drill.exec.proto.SchemaDefProtos.getDescriptor(),
        });
    internal_static_exec_shared_UserCredentials_descriptor =
      getDescriptor().getMessageTypes().get(0);
    internal_static_exec_shared_UserCredentials_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_UserCredentials_descriptor,
        new java.lang.String[] { "UserName", });
    internal_static_exec_shared_QueryId_descriptor =
      getDescriptor().getMessageTypes().get(1);
    internal_static_exec_shared_QueryId_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_QueryId_descriptor,
        new java.lang.String[] { "Part1", "Part2", });
    internal_static_exec_shared_DrillPBError_descriptor =
      getDescriptor().getMessageTypes().get(2);
    internal_static_exec_shared_DrillPBError_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_DrillPBError_descriptor,
        new java.lang.String[] { "ErrorId", "Endpoint", "ErrorType", "Message", "Exception", "ParsingError", });
    internal_static_exec_shared_ExceptionWrapper_descriptor =
      getDescriptor().getMessageTypes().get(3);
    internal_static_exec_shared_ExceptionWrapper_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_ExceptionWrapper_descriptor,
        new java.lang.String[] { "ExceptionClass", "Message", "StackTrace", "Cause", });
    internal_static_exec_shared_StackTraceElementWrapper_descriptor =
      getDescriptor().getMessageTypes().get(4);
    internal_static_exec_shared_StackTraceElementWrapper_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_StackTraceElementWrapper_descriptor,
        new java.lang.String[] { "ClassName", "FileName", "LineNumber", "MethodName", "IsNativeMethod", });
    internal_static_exec_shared_ParsingError_descriptor =
      getDescriptor().getMessageTypes().get(5);
    internal_static_exec_shared_ParsingError_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_ParsingError_descriptor,
        new java.lang.String[] { "StartColumn", "StartRow", "EndColumn", "EndRow", });
    internal_static_exec_shared_RecordBatchDef_descriptor =
      getDescriptor().getMessageTypes().get(6);
    internal_static_exec_shared_RecordBatchDef_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_RecordBatchDef_descriptor,
        new java.lang.String[] { "RecordCount", "Field", "CarriesTwoByteSelectionVector", "AffectedRowsCount", });
    internal_static_exec_shared_NamePart_descriptor =
      getDescriptor().getMessageTypes().get(7);
    internal_static_exec_shared_NamePart_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_NamePart_descriptor,
        new java.lang.String[] { "Type", "Name", "Child", });
    internal_static_exec_shared_SerializedField_descriptor =
      getDescriptor().getMessageTypes().get(8);
    internal_static_exec_shared_SerializedField_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_SerializedField_descriptor,
        new java.lang.String[] { "MajorType", "NamePart", "Child", "ValueCount", "VarByteLength", "BufferLength", });
    internal_static_exec_shared_NodeStatus_descriptor =
      getDescriptor().getMessageTypes().get(9);
    internal_static_exec_shared_NodeStatus_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_NodeStatus_descriptor,
        new java.lang.String[] { "NodeId", "MemoryFootprint", });
    internal_static_exec_shared_QueryResult_descriptor =
      getDescriptor().getMessageTypes().get(10);
    internal_static_exec_shared_QueryResult_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_QueryResult_descriptor,
        new java.lang.String[] { "QueryState", "QueryId", "Error", });
    internal_static_exec_shared_QueryData_descriptor =
      getDescriptor().getMessageTypes().get(11);
    internal_static_exec_shared_QueryData_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_QueryData_descriptor,
        new java.lang.String[] { "QueryId", "RowCount", "Def", "AffectedRowsCount", });
    internal_static_exec_shared_QueryInfo_descriptor =
      getDescriptor().getMessageTypes().get(12);
    internal_static_exec_shared_QueryInfo_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_QueryInfo_descriptor,
        new java.lang.String[] { "Query", "Start", "State", "User", "Foreman", "OptionsJson", "TotalCost", "QueueName", });
    internal_static_exec_shared_QueryProfile_descriptor =
      getDescriptor().getMessageTypes().get(13);
    internal_static_exec_shared_QueryProfile_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_QueryProfile_descriptor,
        new java.lang.String[] { "Id", "Type", "Start", "End", "Query", "Plan", "Foreman", "State", "TotalFragments", "FinishedFragments", "FragmentProfile", "User", "Error", "VerboseError", "ErrorId", "ErrorNode", "OptionsJson", "PlanEnd", "QueueWaitEnd", "TotalCost", "QueueName", "QueryId", "AutoLimit", "ScannedPlugins", });
    internal_static_exec_shared_MajorFragmentProfile_descriptor =
      getDescriptor().getMessageTypes().get(14);
    internal_static_exec_shared_MajorFragmentProfile_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_MajorFragmentProfile_descriptor,
        new java.lang.String[] { "MajorFragmentId", "MinorFragmentProfile", });
    internal_static_exec_shared_MinorFragmentProfile_descriptor =
      getDescriptor().getMessageTypes().get(15);
    internal_static_exec_shared_MinorFragmentProfile_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_MinorFragmentProfile_descriptor,
        new java.lang.String[] { "State", "Error", "MinorFragmentId", "OperatorProfile", "StartTime", "EndTime", "MemoryUsed", "MaxMemoryUsed", "Endpoint", "LastUpdate", "LastProgress", });
    internal_static_exec_shared_OperatorProfile_descriptor =
      getDescriptor().getMessageTypes().get(16);
    internal_static_exec_shared_OperatorProfile_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_OperatorProfile_descriptor,
        new java.lang.String[] { "InputProfile", "OperatorId", "OperatorType", "SetupNanos", "ProcessNanos", "PeakLocalMemoryAllocated", "Metric", "WaitNanos", "OperatorTypeName", });
    internal_static_exec_shared_StreamProfile_descriptor =
      getDescriptor().getMessageTypes().get(17);
    internal_static_exec_shared_StreamProfile_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_StreamProfile_descriptor,
        new java.lang.String[] { "Records", "Batches", "Schemas", });
    internal_static_exec_shared_MetricValue_descriptor =
      getDescriptor().getMessageTypes().get(18);
    internal_static_exec_shared_MetricValue_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_MetricValue_descriptor,
        new java.lang.String[] { "MetricId", "LongValue", "DoubleValue", });
    internal_static_exec_shared_Registry_descriptor =
      getDescriptor().getMessageTypes().get(19);
    internal_static_exec_shared_Registry_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_Registry_descriptor,
        new java.lang.String[] { "Jar", });
    internal_static_exec_shared_Jar_descriptor =
      getDescriptor().getMessageTypes().get(20);
    internal_static_exec_shared_Jar_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_Jar_descriptor,
        new java.lang.String[] { "Name", "FunctionSignature", });
    internal_static_exec_shared_SaslMessage_descriptor =
      getDescriptor().getMessageTypes().get(21);
    internal_static_exec_shared_SaslMessage_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_SaslMessage_descriptor,
        new java.lang.String[] { "Mechanism", "Data", "Status", });
    org.apache.drill.common.types.TypeProtos.getDescriptor();
    org.apache.drill.exec.proto.CoordinationProtos.getDescriptor();
    org.apache.drill.exec.proto.SchemaDefProtos.getDescriptor();
  }

  // @@protoc_insertion_point(outer_class_scope)
}
