/*
 * 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;
    }

    /**
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static RpcChannel valueOf(int value) {
      return forNumber(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;
    }

    /**
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static QueryType valueOf(int value) {
      return forNumber(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;
    }

    /**
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static FragmentState valueOf(int value) {
      return forNumber(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.CoreOperatorType}
   */
  public enum CoreOperatorType
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <code>SINGLE_SENDER = 0;</code>
     */
    SINGLE_SENDER(0),
    /**
     * <code>BROADCAST_SENDER = 1;</code>
     */
    BROADCAST_SENDER(1),
    /**
     * <code>FILTER = 2;</code>
     */
    FILTER(2),
    /**
     * <code>HASH_AGGREGATE = 3;</code>
     */
    HASH_AGGREGATE(3),
    /**
     * <code>HASH_JOIN = 4;</code>
     */
    HASH_JOIN(4),
    /**
     * <code>MERGE_JOIN = 5;</code>
     */
    MERGE_JOIN(5),
    /**
     * <code>HASH_PARTITION_SENDER = 6;</code>
     */
    HASH_PARTITION_SENDER(6),
    /**
     * <code>LIMIT = 7;</code>
     */
    LIMIT(7),
    /**
     * <code>MERGING_RECEIVER = 8;</code>
     */
    MERGING_RECEIVER(8),
    /**
     * <code>ORDERED_PARTITION_SENDER = 9;</code>
     */
    ORDERED_PARTITION_SENDER(9),
    /**
     * <code>PROJECT = 10;</code>
     */
    PROJECT(10),
    /**
     * <code>UNORDERED_RECEIVER = 11;</code>
     */
    UNORDERED_RECEIVER(11),
    /**
     * <code>RANGE_PARTITION_SENDER = 12;</code>
     */
    RANGE_PARTITION_SENDER(12),
    /**
     * <code>SCREEN = 13;</code>
     */
    SCREEN(13),
    /**
     * <code>SELECTION_VECTOR_REMOVER = 14;</code>
     */
    SELECTION_VECTOR_REMOVER(14),
    /**
     * <code>STREAMING_AGGREGATE = 15;</code>
     */
    STREAMING_AGGREGATE(15),
    /**
     * <code>TOP_N_SORT = 16;</code>
     */
    TOP_N_SORT(16),
    /**
     * <code>EXTERNAL_SORT = 17;</code>
     */
    EXTERNAL_SORT(17),
    /**
     * <code>TRACE = 18;</code>
     */
    TRACE(18),
    /**
     * <code>UNION = 19;</code>
     */
    UNION(19),
    /**
     * <code>OLD_SORT = 20;</code>
     */
    OLD_SORT(20),
    /**
     * <code>PARQUET_ROW_GROUP_SCAN = 21;</code>
     */
    PARQUET_ROW_GROUP_SCAN(21),
    /**
     * <code>HIVE_SUB_SCAN = 22;</code>
     */
    HIVE_SUB_SCAN(22),
    /**
     * <code>SYSTEM_TABLE_SCAN = 23;</code>
     */
    SYSTEM_TABLE_SCAN(23),
    /**
     * <code>MOCK_SUB_SCAN = 24;</code>
     */
    MOCK_SUB_SCAN(24),
    /**
     * <code>PARQUET_WRITER = 25;</code>
     */
    PARQUET_WRITER(25),
    /**
     * <code>DIRECT_SUB_SCAN = 26;</code>
     */
    DIRECT_SUB_SCAN(26),
    /**
     * <code>TEXT_WRITER = 27;</code>
     */
    TEXT_WRITER(27),
    /**
     * <code>TEXT_SUB_SCAN = 28;</code>
     */
    TEXT_SUB_SCAN(28),
    /**
     * <code>JSON_SUB_SCAN = 29;</code>
     */
    JSON_SUB_SCAN(29),
    /**
     * <code>INFO_SCHEMA_SUB_SCAN = 30;</code>
     */
    INFO_SCHEMA_SUB_SCAN(30),
    /**
     * <code>COMPLEX_TO_JSON = 31;</code>
     */
    COMPLEX_TO_JSON(31),
    /**
     * <code>PRODUCER_CONSUMER = 32;</code>
     */
    PRODUCER_CONSUMER(32),
    /**
     * <code>HBASE_SUB_SCAN = 33;</code>
     */
    HBASE_SUB_SCAN(33),
    /**
     * <code>WINDOW = 34;</code>
     */
    WINDOW(34),
    /**
     * <code>NESTED_LOOP_JOIN = 35;</code>
     */
    NESTED_LOOP_JOIN(35),
    /**
     * <code>AVRO_SUB_SCAN = 36;</code>
     */
    AVRO_SUB_SCAN(36),
    /**
     * <code>PCAP_SUB_SCAN = 37;</code>
     */
    PCAP_SUB_SCAN(37),
    /**
     * <code>KAFKA_SUB_SCAN = 38;</code>
     */
    KAFKA_SUB_SCAN(38),
    /**
     * <code>KUDU_SUB_SCAN = 39;</code>
     */
    KUDU_SUB_SCAN(39),
    /**
     * <code>FLATTEN = 40;</code>
     */
    FLATTEN(40),
    /**
     * <code>LATERAL_JOIN = 41;</code>
     */
    LATERAL_JOIN(41),
    /**
     * <code>UNNEST = 42;</code>
     */
    UNNEST(42),
    /**
     * <code>HIVE_DRILL_NATIVE_PARQUET_ROW_GROUP_SCAN = 43;</code>
     */
    HIVE_DRILL_NATIVE_PARQUET_ROW_GROUP_SCAN(43),
    /**
     * <code>JDBC_SCAN = 44;</code>
     */
    JDBC_SCAN(44),
    /**
     * <code>REGEX_SUB_SCAN = 45;</code>
     */
    REGEX_SUB_SCAN(45),
    /**
     * <code>MAPRDB_SUB_SCAN = 46;</code>
     */
    MAPRDB_SUB_SCAN(46),
    /**
     * <code>MONGO_SUB_SCAN = 47;</code>
     */
    MONGO_SUB_SCAN(47),
    /**
     * <code>KUDU_WRITER = 48;</code>
     */
    KUDU_WRITER(48),
    /**
     * <code>OPEN_TSDB_SUB_SCAN = 49;</code>
     */
    OPEN_TSDB_SUB_SCAN(49),
    /**
     * <code>JSON_WRITER = 50;</code>
     */
    JSON_WRITER(50),
    /**
     * <code>HTPPD_LOG_SUB_SCAN = 51;</code>
     */
    HTPPD_LOG_SUB_SCAN(51),
    /**
     * <code>IMAGE_SUB_SCAN = 52;</code>
     */
    IMAGE_SUB_SCAN(52),
    /**
     * <code>SEQUENCE_SUB_SCAN = 53;</code>
     */
    SEQUENCE_SUB_SCAN(53),
    /**
     * <code>PARTITION_LIMIT = 54;</code>
     */
    PARTITION_LIMIT(54),
    /**
     * <code>PCAPNG_SUB_SCAN = 55;</code>
     */
    PCAPNG_SUB_SCAN(55),
    /**
     * <code>RUNTIME_FILTER = 56;</code>
     */
    RUNTIME_FILTER(56),
    /**
     * <code>ROWKEY_JOIN = 57;</code>
     */
    ROWKEY_JOIN(57),
    /**
     * <code>SYSLOG_SUB_SCAN = 58;</code>
     */
    SYSLOG_SUB_SCAN(58),
    /**
     * <code>STATISTICS_AGGREGATE = 59;</code>
     */
    STATISTICS_AGGREGATE(59),
    /**
     * <code>UNPIVOT_MAPS = 60;</code>
     */
    UNPIVOT_MAPS(60),
    /**
     * <code>STATISTICS_MERGE = 61;</code>
     */
    STATISTICS_MERGE(61),
    /**
     * <code>LTSV_SUB_SCAN = 62;</code>
     */
    LTSV_SUB_SCAN(62),
    /**
     * <code>HDF5_SUB_SCAN = 63;</code>
     */
    HDF5_SUB_SCAN(63),
    /**
     * <code>EXCEL_SUB_SCAN = 64;</code>
     */
    EXCEL_SUB_SCAN(64),
    /**
     * <code>SHP_SUB_SCAN = 65;</code>
     */
    SHP_SUB_SCAN(65),
    /**
     * <code>METADATA_HANDLER = 66;</code>
     */
    METADATA_HANDLER(66),
    /**
     * <code>METADATA_CONTROLLER = 67;</code>
     */
    METADATA_CONTROLLER(67),
    ;

    /**
     * <code>SINGLE_SENDER = 0;</code>
     */
    public static final int SINGLE_SENDER_VALUE = 0;
    /**
     * <code>BROADCAST_SENDER = 1;</code>
     */
    public static final int BROADCAST_SENDER_VALUE = 1;
    /**
     * <code>FILTER = 2;</code>
     */
    public static final int FILTER_VALUE = 2;
    /**
     * <code>HASH_AGGREGATE = 3;</code>
     */
    public static final int HASH_AGGREGATE_VALUE = 3;
    /**
     * <code>HASH_JOIN = 4;</code>
     */
    public static final int HASH_JOIN_VALUE = 4;
    /**
     * <code>MERGE_JOIN = 5;</code>
     */
    public static final int MERGE_JOIN_VALUE = 5;
    /**
     * <code>HASH_PARTITION_SENDER = 6;</code>
     */
    public static final int HASH_PARTITION_SENDER_VALUE = 6;
    /**
     * <code>LIMIT = 7;</code>
     */
    public static final int LIMIT_VALUE = 7;
    /**
     * <code>MERGING_RECEIVER = 8;</code>
     */
    public static final int MERGING_RECEIVER_VALUE = 8;
    /**
     * <code>ORDERED_PARTITION_SENDER = 9;</code>
     */
    public static final int ORDERED_PARTITION_SENDER_VALUE = 9;
    /**
     * <code>PROJECT = 10;</code>
     */
    public static final int PROJECT_VALUE = 10;
    /**
     * <code>UNORDERED_RECEIVER = 11;</code>
     */
    public static final int UNORDERED_RECEIVER_VALUE = 11;
    /**
     * <code>RANGE_PARTITION_SENDER = 12;</code>
     */
    public static final int RANGE_PARTITION_SENDER_VALUE = 12;
    /**
     * <code>SCREEN = 13;</code>
     */
    public static final int SCREEN_VALUE = 13;
    /**
     * <code>SELECTION_VECTOR_REMOVER = 14;</code>
     */
    public static final int SELECTION_VECTOR_REMOVER_VALUE = 14;
    /**
     * <code>STREAMING_AGGREGATE = 15;</code>
     */
    public static final int STREAMING_AGGREGATE_VALUE = 15;
    /**
     * <code>TOP_N_SORT = 16;</code>
     */
    public static final int TOP_N_SORT_VALUE = 16;
    /**
     * <code>EXTERNAL_SORT = 17;</code>
     */
    public static final int EXTERNAL_SORT_VALUE = 17;
    /**
     * <code>TRACE = 18;</code>
     */
    public static final int TRACE_VALUE = 18;
    /**
     * <code>UNION = 19;</code>
     */
    public static final int UNION_VALUE = 19;
    /**
     * <code>OLD_SORT = 20;</code>
     */
    public static final int OLD_SORT_VALUE = 20;
    /**
     * <code>PARQUET_ROW_GROUP_SCAN = 21;</code>
     */
    public static final int PARQUET_ROW_GROUP_SCAN_VALUE = 21;
    /**
     * <code>HIVE_SUB_SCAN = 22;</code>
     */
    public static final int HIVE_SUB_SCAN_VALUE = 22;
    /**
     * <code>SYSTEM_TABLE_SCAN = 23;</code>
     */
    public static final int SYSTEM_TABLE_SCAN_VALUE = 23;
    /**
     * <code>MOCK_SUB_SCAN = 24;</code>
     */
    public static final int MOCK_SUB_SCAN_VALUE = 24;
    /**
     * <code>PARQUET_WRITER = 25;</code>
     */
    public static final int PARQUET_WRITER_VALUE = 25;
    /**
     * <code>DIRECT_SUB_SCAN = 26;</code>
     */
    public static final int DIRECT_SUB_SCAN_VALUE = 26;
    /**
     * <code>TEXT_WRITER = 27;</code>
     */
    public static final int TEXT_WRITER_VALUE = 27;
    /**
     * <code>TEXT_SUB_SCAN = 28;</code>
     */
    public static final int TEXT_SUB_SCAN_VALUE = 28;
    /**
     * <code>JSON_SUB_SCAN = 29;</code>
     */
    public static final int JSON_SUB_SCAN_VALUE = 29;
    /**
     * <code>INFO_SCHEMA_SUB_SCAN = 30;</code>
     */
    public static final int INFO_SCHEMA_SUB_SCAN_VALUE = 30;
    /**
     * <code>COMPLEX_TO_JSON = 31;</code>
     */
    public static final int COMPLEX_TO_JSON_VALUE = 31;
    /**
     * <code>PRODUCER_CONSUMER = 32;</code>
     */
    public static final int PRODUCER_CONSUMER_VALUE = 32;
    /**
     * <code>HBASE_SUB_SCAN = 33;</code>
     */
    public static final int HBASE_SUB_SCAN_VALUE = 33;
    /**
     * <code>WINDOW = 34;</code>
     */
    public static final int WINDOW_VALUE = 34;
    /**
     * <code>NESTED_LOOP_JOIN = 35;</code>
     */
    public static final int NESTED_LOOP_JOIN_VALUE = 35;
    /**
     * <code>AVRO_SUB_SCAN = 36;</code>
     */
    public static final int AVRO_SUB_SCAN_VALUE = 36;
    /**
     * <code>PCAP_SUB_SCAN = 37;</code>
     */
    public static final int PCAP_SUB_SCAN_VALUE = 37;
    /**
     * <code>KAFKA_SUB_SCAN = 38;</code>
     */
    public static final int KAFKA_SUB_SCAN_VALUE = 38;
    /**
     * <code>KUDU_SUB_SCAN = 39;</code>
     */
    public static final int KUDU_SUB_SCAN_VALUE = 39;
    /**
     * <code>FLATTEN = 40;</code>
     */
    public static final int FLATTEN_VALUE = 40;
    /**
     * <code>LATERAL_JOIN = 41;</code>
     */
    public static final int LATERAL_JOIN_VALUE = 41;
    /**
     * <code>UNNEST = 42;</code>
     */
    public static final int UNNEST_VALUE = 42;
    /**
     * <code>HIVE_DRILL_NATIVE_PARQUET_ROW_GROUP_SCAN = 43;</code>
     */
    public static final int HIVE_DRILL_NATIVE_PARQUET_ROW_GROUP_SCAN_VALUE = 43;
    /**
     * <code>JDBC_SCAN = 44;</code>
     */
    public static final int JDBC_SCAN_VALUE = 44;
    /**
     * <code>REGEX_SUB_SCAN = 45;</code>
     */
    public static final int REGEX_SUB_SCAN_VALUE = 45;
    /**
     * <code>MAPRDB_SUB_SCAN = 46;</code>
     */
    public static final int MAPRDB_SUB_SCAN_VALUE = 46;
    /**
     * <code>MONGO_SUB_SCAN = 47;</code>
     */
    public static final int MONGO_SUB_SCAN_VALUE = 47;
    /**
     * <code>KUDU_WRITER = 48;</code>
     */
    public static final int KUDU_WRITER_VALUE = 48;
    /**
     * <code>OPEN_TSDB_SUB_SCAN = 49;</code>
     */
    public static final int OPEN_TSDB_SUB_SCAN_VALUE = 49;
    /**
     * <code>JSON_WRITER = 50;</code>
     */
    public static final int JSON_WRITER_VALUE = 50;
    /**
     * <code>HTPPD_LOG_SUB_SCAN = 51;</code>
     */
    public static final int HTPPD_LOG_SUB_SCAN_VALUE = 51;
    /**
     * <code>IMAGE_SUB_SCAN = 52;</code>
     */
    public static final int IMAGE_SUB_SCAN_VALUE = 52;
    /**
     * <code>SEQUENCE_SUB_SCAN = 53;</code>
     */
    public static final int SEQUENCE_SUB_SCAN_VALUE = 53;
    /**
     * <code>PARTITION_LIMIT = 54;</code>
     */
    public static final int PARTITION_LIMIT_VALUE = 54;
    /**
     * <code>PCAPNG_SUB_SCAN = 55;</code>
     */
    public static final int PCAPNG_SUB_SCAN_VALUE = 55;
    /**
     * <code>RUNTIME_FILTER = 56;</code>
     */
    public static final int RUNTIME_FILTER_VALUE = 56;
    /**
     * <code>ROWKEY_JOIN = 57;</code>
     */
    public static final int ROWKEY_JOIN_VALUE = 57;
    /**
     * <code>SYSLOG_SUB_SCAN = 58;</code>
     */
    public static final int SYSLOG_SUB_SCAN_VALUE = 58;
    /**
     * <code>STATISTICS_AGGREGATE = 59;</code>
     */
    public static final int STATISTICS_AGGREGATE_VALUE = 59;
    /**
     * <code>UNPIVOT_MAPS = 60;</code>
     */
    public static final int UNPIVOT_MAPS_VALUE = 60;
    /**
     * <code>STATISTICS_MERGE = 61;</code>
     */
    public static final int STATISTICS_MERGE_VALUE = 61;
    /**
     * <code>LTSV_SUB_SCAN = 62;</code>
     */
    public static final int LTSV_SUB_SCAN_VALUE = 62;
    /**
     * <code>HDF5_SUB_SCAN = 63;</code>
     */
    public static final int HDF5_SUB_SCAN_VALUE = 63;
    /**
     * <code>EXCEL_SUB_SCAN = 64;</code>
     */
    public static final int EXCEL_SUB_SCAN_VALUE = 64;
    /**
     * <code>SHP_SUB_SCAN = 65;</code>
     */
    public static final int SHP_SUB_SCAN_VALUE = 65;
    /**
     * <code>METADATA_HANDLER = 66;</code>
     */
    public static final int METADATA_HANDLER_VALUE = 66;
    /**
     * <code>METADATA_CONTROLLER = 67;</code>
     */
    public static final int METADATA_CONTROLLER_VALUE = 67;


    public final int getNumber() {
      return value;
    }

    /**
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static CoreOperatorType valueOf(int value) {
      return forNumber(value);
    }

    public static CoreOperatorType forNumber(int value) {
      switch (value) {
        case 0: return SINGLE_SENDER;
        case 1: return BROADCAST_SENDER;
        case 2: return FILTER;
        case 3: return HASH_AGGREGATE;
        case 4: return HASH_JOIN;
        case 5: return MERGE_JOIN;
        case 6: return HASH_PARTITION_SENDER;
        case 7: return LIMIT;
        case 8: return MERGING_RECEIVER;
        case 9: return ORDERED_PARTITION_SENDER;
        case 10: return PROJECT;
        case 11: return UNORDERED_RECEIVER;
        case 12: return RANGE_PARTITION_SENDER;
        case 13: return SCREEN;
        case 14: return SELECTION_VECTOR_REMOVER;
        case 15: return STREAMING_AGGREGATE;
        case 16: return TOP_N_SORT;
        case 17: return EXTERNAL_SORT;
        case 18: return TRACE;
        case 19: return UNION;
        case 20: return OLD_SORT;
        case 21: return PARQUET_ROW_GROUP_SCAN;
        case 22: return HIVE_SUB_SCAN;
        case 23: return SYSTEM_TABLE_SCAN;
        case 24: return MOCK_SUB_SCAN;
        case 25: return PARQUET_WRITER;
        case 26: return DIRECT_SUB_SCAN;
        case 27: return TEXT_WRITER;
        case 28: return TEXT_SUB_SCAN;
        case 29: return JSON_SUB_SCAN;
        case 30: return INFO_SCHEMA_SUB_SCAN;
        case 31: return COMPLEX_TO_JSON;
        case 32: return PRODUCER_CONSUMER;
        case 33: return HBASE_SUB_SCAN;
        case 34: return WINDOW;
        case 35: return NESTED_LOOP_JOIN;
        case 36: return AVRO_SUB_SCAN;
        case 37: return PCAP_SUB_SCAN;
        case 38: return KAFKA_SUB_SCAN;
        case 39: return KUDU_SUB_SCAN;
        case 40: return FLATTEN;
        case 41: return LATERAL_JOIN;
        case 42: return UNNEST;
        case 43: return HIVE_DRILL_NATIVE_PARQUET_ROW_GROUP_SCAN;
        case 44: return JDBC_SCAN;
        case 45: return REGEX_SUB_SCAN;
        case 46: return MAPRDB_SUB_SCAN;
        case 47: return MONGO_SUB_SCAN;
        case 48: return KUDU_WRITER;
        case 49: return OPEN_TSDB_SUB_SCAN;
        case 50: return JSON_WRITER;
        case 51: return HTPPD_LOG_SUB_SCAN;
        case 52: return IMAGE_SUB_SCAN;
        case 53: return SEQUENCE_SUB_SCAN;
        case 54: return PARTITION_LIMIT;
        case 55: return PCAPNG_SUB_SCAN;
        case 56: return RUNTIME_FILTER;
        case 57: return ROWKEY_JOIN;
        case 58: return SYSLOG_SUB_SCAN;
        case 59: return STATISTICS_AGGREGATE;
        case 60: return UNPIVOT_MAPS;
        case 61: return STATISTICS_MERGE;
        case 62: return LTSV_SUB_SCAN;
        case 63: return HDF5_SUB_SCAN;
        case 64: return EXCEL_SUB_SCAN;
        case 65: return SHP_SUB_SCAN;
        case 66: return METADATA_HANDLER;
        case 67: return METADATA_CONTROLLER;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<CoreOperatorType>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        CoreOperatorType> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<CoreOperatorType>() {
            public CoreOperatorType findValueByNumber(int number) {
              return CoreOperatorType.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 CoreOperatorType[] VALUES = values();

    public static CoreOperatorType 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 CoreOperatorType(int value) {
      this.value = value;
    }

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

  /**
   * 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;
    }

    /**
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static SaslStatus valueOf(int value) {
      return forNumber(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(4);
    }

    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>
     */
    boolean hasUserName();
    /**
     * <code>optional string user_name = 1;</code>
     */
    java.lang.String getUserName();
    /**
     * <code>optional string user_name = 1;</code>
     */
    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
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private UserCredentials(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 10: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00000001;
              userName_ = bs;
              break;
            }
            default: {
              if (!parseUnknownField(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.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>
     */
    public boolean hasUserName() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional string user_name = 1;</code>
     */
    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>
     */
    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) == 0x00000001)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, userName_);
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, userName_);
      }
      size += unknownFields.getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.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;

      boolean result = true;
      result = result && (hasUserName() == other.hasUserName());
      if (hasUserName()) {
        result = result && getUserName()
            .equals(other.getUserName());
      }
      result = result && unknownFields.equals(other.unknownFields);
      return result;
    }

    @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) + unknownFields.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() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        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) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.userName_ = userName_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return (Builder) super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return (Builder) super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return (Builder) super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return (Builder) super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) 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.unknownFields);
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.drill.exec.proto.UserBitShared.UserCredentials parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.drill.exec.proto.UserBitShared.UserCredentials) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private java.lang.Object userName_ = "";
      /**
       * <code>optional string user_name = 1;</code>
       */
      public boolean hasUserName() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional string user_name = 1;</code>
       */
      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>
       */
      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>
       */
      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>
       */
      public Builder clearUserName() {
        bitField0_ = (bitField0_ & ~0x00000001);
        userName_ = getDefaultInstance().getUserName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string user_name = 1;</code>
       */
      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 {
        return new UserCredentials(input, extensionRegistry);
      }
    };

    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>
     */
    boolean hasPart1();
    /**
     * <code>optional sfixed64 part1 = 1;</code>
     */
    long getPart1();

    /**
     * <code>optional sfixed64 part2 = 2;</code>
     */
    boolean hasPart2();
    /**
     * <code>optional sfixed64 part2 = 2;</code>
     */
    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() {
      part1_ = 0L;
      part2_ = 0L;
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private QueryId(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 9: {
              bitField0_ |= 0x00000001;
              part1_ = input.readSFixed64();
              break;
            }
            case 17: {
              bitField0_ |= 0x00000002;
              part2_ = input.readSFixed64();
              break;
            }
            default: {
              if (!parseUnknownField(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.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>
     */
    public boolean hasPart1() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional sfixed64 part1 = 1;</code>
     */
    public long getPart1() {
      return part1_;
    }

    public static final int PART2_FIELD_NUMBER = 2;
    private long part2_;
    /**
     * <code>optional sfixed64 part2 = 2;</code>
     */
    public boolean hasPart2() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional sfixed64 part2 = 2;</code>
     */
    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) == 0x00000001)) {
        output.writeSFixed64(1, part1_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeSFixed64(2, part2_);
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeSFixed64Size(1, part1_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeSFixed64Size(2, part2_);
      }
      size += unknownFields.getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.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;

      boolean result = true;
      result = result && (hasPart1() == other.hasPart1());
      if (hasPart1()) {
        result = result && (getPart1()
            == other.getPart1());
      }
      result = result && (hasPart2() == other.hasPart2());
      if (hasPart2()) {
        result = result && (getPart2()
            == other.getPart2());
      }
      result = result && unknownFields.equals(other.unknownFields);
      return result;
    }

    @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) + unknownFields.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() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        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) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.part1_ = part1_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.part2_ = part2_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return (Builder) super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return (Builder) super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return (Builder) super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return (Builder) super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) 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.unknownFields);
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.drill.exec.proto.UserBitShared.QueryId parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.drill.exec.proto.UserBitShared.QueryId) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private long part1_ ;
      /**
       * <code>optional sfixed64 part1 = 1;</code>
       */
      public boolean hasPart1() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional sfixed64 part1 = 1;</code>
       */
      public long getPart1() {
        return part1_;
      }
      /**
       * <code>optional sfixed64 part1 = 1;</code>
       */
      public Builder setPart1(long value) {
        bitField0_ |= 0x00000001;
        part1_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional sfixed64 part1 = 1;</code>
       */
      public Builder clearPart1() {
        bitField0_ = (bitField0_ & ~0x00000001);
        part1_ = 0L;
        onChanged();
        return this;
      }

      private long part2_ ;
      /**
       * <code>optional sfixed64 part2 = 2;</code>
       */
      public boolean hasPart2() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional sfixed64 part2 = 2;</code>
       */
      public long getPart2() {
        return part2_;
      }
      /**
       * <code>optional sfixed64 part2 = 2;</code>
       */
      public Builder setPart2(long value) {
        bitField0_ |= 0x00000002;
        part2_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional sfixed64 part2 = 2;</code>
       */
      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 {
        return new QueryId(input, extensionRegistry);
      }
    };

    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>
     */
    boolean hasErrorId();
    /**
     * <pre>
     * for debug tracing purposes
     * </pre>
     *
     * <code>optional string error_id = 1;</code>
     */
    java.lang.String getErrorId();
    /**
     * <pre>
     * for debug tracing purposes
     * </pre>
     *
     * <code>optional string error_id = 1;</code>
     */
    com.google.protobuf.ByteString
        getErrorIdBytes();

    /**
     * <code>optional .exec.DrillbitEndpoint endpoint = 2;</code>
     */
    boolean hasEndpoint();
    /**
     * <code>optional .exec.DrillbitEndpoint endpoint = 2;</code>
     */
    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>
     */
    boolean hasErrorType();
    /**
     * <code>optional .exec.shared.DrillPBError.ErrorType error_type = 3;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType getErrorType();

    /**
     * <code>optional string message = 4;</code>
     */
    boolean hasMessage();
    /**
     * <code>optional string message = 4;</code>
     */
    java.lang.String getMessage();
    /**
     * <code>optional string message = 4;</code>
     */
    com.google.protobuf.ByteString
        getMessageBytes();

    /**
     * <code>optional .exec.shared.ExceptionWrapper exception = 5;</code>
     */
    boolean hasException();
    /**
     * <code>optional .exec.shared.ExceptionWrapper exception = 5;</code>
     */
    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
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private DrillPBError(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 10: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00000001;
              errorId_ = bs;
              break;
            }
            case 18: {
              org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder subBuilder = null;
              if (((bitField0_ & 0x00000002) == 0x00000002)) {
                subBuilder = endpoint_.toBuilder();
              }
              endpoint_ = input.readMessage(org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(endpoint_);
                endpoint_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000002;
              break;
            }
            case 24: {
              int rawValue = input.readEnum();
                @SuppressWarnings("deprecation")
              org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType value = org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType.valueOf(rawValue);
              if (value == null) {
                unknownFields.mergeVarintField(3, rawValue);
              } else {
                bitField0_ |= 0x00000004;
                errorType_ = rawValue;
              }
              break;
            }
            case 34: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00000008;
              message_ = bs;
              break;
            }
            case 42: {
              org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.Builder subBuilder = null;
              if (((bitField0_ & 0x00000010) == 0x00000010)) {
                subBuilder = exception_.toBuilder();
              }
              exception_ = input.readMessage(org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(exception_);
                exception_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000010;
              break;
            }
            case 50: {
              if (!((mutable_bitField0_ & 0x00000020) == 0x00000020)) {
                parsingError_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserBitShared.ParsingError>();
                mutable_bitField0_ |= 0x00000020;
              }
              parsingError_.add(
                  input.readMessage(org.apache.drill.exec.proto.UserBitShared.ParsingError.PARSER, extensionRegistry));
              break;
            }
            default: {
              if (!parseUnknownField(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000020) == 0x00000020)) {
          parsingError_ = java.util.Collections.unmodifiableList(parsingError_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    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>
       * 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;


      public final int getNumber() {
        return value;
      }

      /**
       * @deprecated Use {@link #forNumber(int)} instead.
       */
      @java.lang.Deprecated
      public static ErrorType valueOf(int value) {
        return forNumber(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;
          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>
     */
    public boolean hasErrorId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <pre>
     * for debug tracing purposes
     * </pre>
     *
     * <code>optional string error_id = 1;</code>
     */
    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>
     */
    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>
     */
    public boolean hasEndpoint() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional .exec.DrillbitEndpoint endpoint = 2;</code>
     */
    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>
     */
    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>
     */
    public boolean hasErrorType() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional .exec.shared.DrillPBError.ErrorType error_type = 3;</code>
     */
    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>
     */
    public boolean hasMessage() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>optional string message = 4;</code>
     */
    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>
     */
    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>
     */
    public boolean hasException() {
      return ((bitField0_ & 0x00000010) == 0x00000010);
    }
    /**
     * <code>optional .exec.shared.ExceptionWrapper exception = 5;</code>
     */
    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>
     */
    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>
     */
    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>
     */
    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>
     */
    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>
     */
    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>
     */
    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) == 0x00000001)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, errorId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeMessage(2, getEndpoint());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeEnum(3, errorType_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 4, message_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        output.writeMessage(5, getException());
      }
      for (int i = 0; i < parsingError_.size(); i++) {
        output.writeMessage(6, parsingError_.get(i));
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, errorId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, getEndpoint());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(3, errorType_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, message_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        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 += unknownFields.getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.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;

      boolean result = true;
      result = result && (hasErrorId() == other.hasErrorId());
      if (hasErrorId()) {
        result = result && getErrorId()
            .equals(other.getErrorId());
      }
      result = result && (hasEndpoint() == other.hasEndpoint());
      if (hasEndpoint()) {
        result = result && getEndpoint()
            .equals(other.getEndpoint());
      }
      result = result && (hasErrorType() == other.hasErrorType());
      if (hasErrorType()) {
        result = result && errorType_ == other.errorType_;
      }
      result = result && (hasMessage() == other.hasMessage());
      if (hasMessage()) {
        result = result && getMessage()
            .equals(other.getMessage());
      }
      result = result && (hasException() == other.hasException());
      if (hasException()) {
        result = result && getException()
            .equals(other.getException());
      }
      result = result && getParsingErrorList()
          .equals(other.getParsingErrorList());
      result = result && unknownFields.equals(other.unknownFields);
      return result;
    }

    @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) + unknownFields.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();
          bitField0_ = (bitField0_ & ~0x00000020);
        } else {
          parsingErrorBuilder_.clear();
        }
        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) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.errorId_ = errorId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        if (endpointBuilder_ == null) {
          result.endpoint_ = endpoint_;
        } else {
          result.endpoint_ = endpointBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.errorType_ = errorType_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.message_ = message_;
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000010;
        }
        if (exceptionBuilder_ == null) {
          result.exception_ = exception_;
        } else {
          result.exception_ = exceptionBuilder_.build();
        }
        if (parsingErrorBuilder_ == null) {
          if (((bitField0_ & 0x00000020) == 0x00000020)) {
            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 (Builder) super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return (Builder) super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return (Builder) super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return (Builder) super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) 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.unknownFields);
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.drill.exec.proto.UserBitShared.DrillPBError parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.drill.exec.proto.UserBitShared.DrillPBError) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private java.lang.Object errorId_ = "";
      /**
       * <pre>
       * for debug tracing purposes
       * </pre>
       *
       * <code>optional string error_id = 1;</code>
       */
      public boolean hasErrorId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <pre>
       * for debug tracing purposes
       * </pre>
       *
       * <code>optional string error_id = 1;</code>
       */
      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>
       */
      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>
       */
      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>
       */
      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>
       */
      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_ = null;
      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>
       */
      public boolean hasEndpoint() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 2;</code>
       */
      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) == 0x00000002) &&
              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>
       */
      public boolean hasErrorType() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional .exec.shared.DrillPBError.ErrorType error_type = 3;</code>
       */
      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>
       */
      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>
       */
      public Builder clearErrorType() {
        bitField0_ = (bitField0_ & ~0x00000004);
        errorType_ = 0;
        onChanged();
        return this;
      }

      private java.lang.Object message_ = "";
      /**
       * <code>optional string message = 4;</code>
       */
      public boolean hasMessage() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>optional string message = 4;</code>
       */
      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>
       */
      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>
       */
      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>
       */
      public Builder clearMessage() {
        bitField0_ = (bitField0_ & ~0x00000008);
        message_ = getDefaultInstance().getMessage();
        onChanged();
        return this;
      }
      /**
       * <code>optional string message = 4;</code>
       */
      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_ = null;
      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>
       */
      public boolean hasException() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      /**
       * <code>optional .exec.shared.ExceptionWrapper exception = 5;</code>
       */
      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) == 0x00000010) &&
              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) == 0x00000020)) {
          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) == 0x00000020),
                  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 {
        return new DrillPBError(input, extensionRegistry);
      }
    };

    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>
     */
    boolean hasExceptionClass();
    /**
     * <code>optional string exception_class = 1;</code>
     */
    java.lang.String getExceptionClass();
    /**
     * <code>optional string exception_class = 1;</code>
     */
    com.google.protobuf.ByteString
        getExceptionClassBytes();

    /**
     * <code>optional string message = 2;</code>
     */
    boolean hasMessage();
    /**
     * <code>optional string message = 2;</code>
     */
    java.lang.String getMessage();
    /**
     * <code>optional string message = 2;</code>
     */
    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>
     */
    boolean hasCause();
    /**
     * <code>optional .exec.shared.ExceptionWrapper cause = 4;</code>
     */
    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
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private ExceptionWrapper(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 10: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00000001;
              exceptionClass_ = bs;
              break;
            }
            case 18: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00000002;
              message_ = bs;
              break;
            }
            case 26: {
              if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
                stackTrace_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper>();
                mutable_bitField0_ |= 0x00000004;
              }
              stackTrace_.add(
                  input.readMessage(org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper.PARSER, extensionRegistry));
              break;
            }
            case 34: {
              org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.Builder subBuilder = null;
              if (((bitField0_ & 0x00000004) == 0x00000004)) {
                subBuilder = cause_.toBuilder();
              }
              cause_ = input.readMessage(org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(cause_);
                cause_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000004;
              break;
            }
            default: {
              if (!parseUnknownField(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
          stackTrace_ = java.util.Collections.unmodifiableList(stackTrace_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    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>
     */
    public boolean hasExceptionClass() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional string exception_class = 1;</code>
     */
    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>
     */
    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>
     */
    public boolean hasMessage() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional string message = 2;</code>
     */
    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>
     */
    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>
     */
    public java.util.List<org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper> getStackTraceList() {
      return stackTrace_;
    }
    /**
     * <code>repeated .exec.shared.StackTraceElementWrapper stack_trace = 3;</code>
     */
    public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapperOrBuilder> 
        getStackTraceOrBuilderList() {
      return stackTrace_;
    }
    /**
     * <code>repeated .exec.shared.StackTraceElementWrapper stack_trace = 3;</code>
     */
    public int getStackTraceCount() {
      return stackTrace_.size();
    }
    /**
     * <code>repeated .exec.shared.StackTraceElementWrapper stack_trace = 3;</code>
     */
    public org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper getStackTrace(int index) {
      return stackTrace_.get(index);
    }
    /**
     * <code>repeated .exec.shared.StackTraceElementWrapper stack_trace = 3;</code>
     */
    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>
     */
    public boolean hasCause() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional .exec.shared.ExceptionWrapper cause = 4;</code>
     */
    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>
     */
    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) == 0x00000001)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, exceptionClass_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        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) == 0x00000004)) {
        output.writeMessage(4, getCause());
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, exceptionClass_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        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) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(4, getCause());
      }
      size += unknownFields.getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.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;

      boolean result = true;
      result = result && (hasExceptionClass() == other.hasExceptionClass());
      if (hasExceptionClass()) {
        result = result && getExceptionClass()
            .equals(other.getExceptionClass());
      }
      result = result && (hasMessage() == other.hasMessage());
      if (hasMessage()) {
        result = result && getMessage()
            .equals(other.getMessage());
      }
      result = result && getStackTraceList()
          .equals(other.getStackTraceList());
      result = result && (hasCause() == other.hasCause());
      if (hasCause()) {
        result = result && getCause()
            .equals(other.getCause());
      }
      result = result && unknownFields.equals(other.unknownFields);
      return result;
    }

    @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) + unknownFields.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();
          bitField0_ = (bitField0_ & ~0x00000004);
        } else {
          stackTraceBuilder_.clear();
        }
        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) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.exceptionClass_ = exceptionClass_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.message_ = message_;
        if (stackTraceBuilder_ == null) {
          if (((bitField0_ & 0x00000004) == 0x00000004)) {
            stackTrace_ = java.util.Collections.unmodifiableList(stackTrace_);
            bitField0_ = (bitField0_ & ~0x00000004);
          }
          result.stackTrace_ = stackTrace_;
        } else {
          result.stackTrace_ = stackTraceBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000004;
        }
        if (causeBuilder_ == null) {
          result.cause_ = cause_;
        } else {
          result.cause_ = causeBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return (Builder) super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return (Builder) super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return (Builder) super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return (Builder) super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) 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.unknownFields);
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private java.lang.Object exceptionClass_ = "";
      /**
       * <code>optional string exception_class = 1;</code>
       */
      public boolean hasExceptionClass() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional string exception_class = 1;</code>
       */
      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>
       */
      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>
       */
      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>
       */
      public Builder clearExceptionClass() {
        bitField0_ = (bitField0_ & ~0x00000001);
        exceptionClass_ = getDefaultInstance().getExceptionClass();
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception_class = 1;</code>
       */
      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>
       */
      public boolean hasMessage() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional string message = 2;</code>
       */
      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>
       */
      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>
       */
      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>
       */
      public Builder clearMessage() {
        bitField0_ = (bitField0_ & ~0x00000002);
        message_ = getDefaultInstance().getMessage();
        onChanged();
        return this;
      }
      /**
       * <code>optional string message = 2;</code>
       */
      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) == 0x00000004)) {
          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) == 0x00000004),
                  getParentForChildren(),
                  isClean());
          stackTrace_ = null;
        }
        return stackTraceBuilder_;
      }

      private org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper cause_ = null;
      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>
       */
      public boolean hasCause() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>optional .exec.shared.ExceptionWrapper cause = 4;</code>
       */
      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) == 0x00000008) &&
              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 {
        return new ExceptionWrapper(input, extensionRegistry);
      }
    };

    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>
     */
    boolean hasClassName();
    /**
     * <code>optional string class_name = 1;</code>
     */
    java.lang.String getClassName();
    /**
     * <code>optional string class_name = 1;</code>
     */
    com.google.protobuf.ByteString
        getClassNameBytes();

    /**
     * <code>optional string file_name = 2;</code>
     */
    boolean hasFileName();
    /**
     * <code>optional string file_name = 2;</code>
     */
    java.lang.String getFileName();
    /**
     * <code>optional string file_name = 2;</code>
     */
    com.google.protobuf.ByteString
        getFileNameBytes();

    /**
     * <code>optional int32 line_number = 3;</code>
     */
    boolean hasLineNumber();
    /**
     * <code>optional int32 line_number = 3;</code>
     */
    int getLineNumber();

    /**
     * <code>optional string method_name = 4;</code>
     */
    boolean hasMethodName();
    /**
     * <code>optional string method_name = 4;</code>
     */
    java.lang.String getMethodName();
    /**
     * <code>optional string method_name = 4;</code>
     */
    com.google.protobuf.ByteString
        getMethodNameBytes();

    /**
     * <code>optional bool is_native_method = 5;</code>
     */
    boolean hasIsNativeMethod();
    /**
     * <code>optional bool is_native_method = 5;</code>
     */
    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_ = "";
      lineNumber_ = 0;
      methodName_ = "";
      isNativeMethod_ = false;
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private StackTraceElementWrapper(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 10: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00000001;
              className_ = bs;
              break;
            }
            case 18: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00000002;
              fileName_ = bs;
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              lineNumber_ = input.readInt32();
              break;
            }
            case 34: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00000008;
              methodName_ = bs;
              break;
            }
            case 40: {
              bitField0_ |= 0x00000010;
              isNativeMethod_ = input.readBool();
              break;
            }
            default: {
              if (!parseUnknownField(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.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>
     */
    public boolean hasClassName() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional string class_name = 1;</code>
     */
    public java.lang.String getClassName() {
      java.lang.Object ref = className_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          className_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string class_name = 1;</code>
     */
    public com.google.protobuf.ByteString
        getClassNameBytes() {
      java.lang.Object ref = className_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        className_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

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

    public static final int LINE_NUMBER_FIELD_NUMBER = 3;
    private int lineNumber_;
    /**
     * <code>optional int32 line_number = 3;</code>
     */
    public boolean hasLineNumber() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional int32 line_number = 3;</code>
     */
    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>
     */
    public boolean hasMethodName() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>optional string method_name = 4;</code>
     */
    public java.lang.String getMethodName() {
      java.lang.Object ref = methodName_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          methodName_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string method_name = 4;</code>
     */
    public com.google.protobuf.ByteString
        getMethodNameBytes() {
      java.lang.Object ref = methodName_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        methodName_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int IS_NATIVE_METHOD_FIELD_NUMBER = 5;
    private boolean isNativeMethod_;
    /**
     * <code>optional bool is_native_method = 5;</code>
     */
    public boolean hasIsNativeMethod() {
      return ((bitField0_ & 0x00000010) == 0x00000010);
    }
    /**
     * <code>optional bool is_native_method = 5;</code>
     */
    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) == 0x00000001)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, className_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, fileName_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeInt32(3, lineNumber_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 4, methodName_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        output.writeBool(5, isNativeMethod_);
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, className_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, fileName_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(3, lineNumber_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, methodName_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(5, isNativeMethod_);
      }
      size += unknownFields.getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.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;

      boolean result = true;
      result = result && (hasClassName() == other.hasClassName());
      if (hasClassName()) {
        result = result && getClassName()
            .equals(other.getClassName());
      }
      result = result && (hasFileName() == other.hasFileName());
      if (hasFileName()) {
        result = result && getFileName()
            .equals(other.getFileName());
      }
      result = result && (hasLineNumber() == other.hasLineNumber());
      if (hasLineNumber()) {
        result = result && (getLineNumber()
            == other.getLineNumber());
      }
      result = result && (hasMethodName() == other.hasMethodName());
      if (hasMethodName()) {
        result = result && getMethodName()
            .equals(other.getMethodName());
      }
      result = result && (hasIsNativeMethod() == other.hasIsNativeMethod());
      if (hasIsNativeMethod()) {
        result = result && (getIsNativeMethod()
            == other.getIsNativeMethod());
      }
      result = result && unknownFields.equals(other.unknownFields);
      return result;
    }

    @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) + unknownFields.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() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        className_ = "";
        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) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.className_ = className_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.fileName_ = fileName_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.lineNumber_ = lineNumber_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.methodName_ = methodName_;
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000010;
        }
        result.isNativeMethod_ = isNativeMethod_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return (Builder) super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return (Builder) super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return (Builder) super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return (Builder) super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) 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.unknownFields);
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private java.lang.Object className_ = "";
      /**
       * <code>optional string class_name = 1;</code>
       */
      public boolean hasClassName() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional string class_name = 1;</code>
       */
      public java.lang.String getClassName() {
        java.lang.Object ref = className_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            className_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string class_name = 1;</code>
       */
      public com.google.protobuf.ByteString
          getClassNameBytes() {
        java.lang.Object ref = className_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          className_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string class_name = 1;</code>
       */
      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>
       */
      public Builder clearClassName() {
        bitField0_ = (bitField0_ & ~0x00000001);
        className_ = getDefaultInstance().getClassName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string class_name = 1;</code>
       */
      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>
       */
      public boolean hasFileName() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional string file_name = 2;</code>
       */
      public java.lang.String getFileName() {
        java.lang.Object ref = fileName_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            fileName_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string file_name = 2;</code>
       */
      public com.google.protobuf.ByteString
          getFileNameBytes() {
        java.lang.Object ref = fileName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          fileName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string file_name = 2;</code>
       */
      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>
       */
      public Builder clearFileName() {
        bitField0_ = (bitField0_ & ~0x00000002);
        fileName_ = getDefaultInstance().getFileName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string file_name = 2;</code>
       */
      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>
       */
      public boolean hasLineNumber() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional int32 line_number = 3;</code>
       */
      public int getLineNumber() {
        return lineNumber_;
      }
      /**
       * <code>optional int32 line_number = 3;</code>
       */
      public Builder setLineNumber(int value) {
        bitField0_ |= 0x00000004;
        lineNumber_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 line_number = 3;</code>
       */
      public Builder clearLineNumber() {
        bitField0_ = (bitField0_ & ~0x00000004);
        lineNumber_ = 0;
        onChanged();
        return this;
      }

      private java.lang.Object methodName_ = "";
      /**
       * <code>optional string method_name = 4;</code>
       */
      public boolean hasMethodName() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>optional string method_name = 4;</code>
       */
      public java.lang.String getMethodName() {
        java.lang.Object ref = methodName_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            methodName_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string method_name = 4;</code>
       */
      public com.google.protobuf.ByteString
          getMethodNameBytes() {
        java.lang.Object ref = methodName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          methodName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string method_name = 4;</code>
       */
      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>
       */
      public Builder clearMethodName() {
        bitField0_ = (bitField0_ & ~0x00000008);
        methodName_ = getDefaultInstance().getMethodName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string method_name = 4;</code>
       */
      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>
       */
      public boolean hasIsNativeMethod() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      /**
       * <code>optional bool is_native_method = 5;</code>
       */
      public boolean getIsNativeMethod() {
        return isNativeMethod_;
      }
      /**
       * <code>optional bool is_native_method = 5;</code>
       */
      public Builder setIsNativeMethod(boolean value) {
        bitField0_ |= 0x00000010;
        isNativeMethod_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool is_native_method = 5;</code>
       */
      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 {
        return new StackTraceElementWrapper(input, extensionRegistry);
      }
    };

    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>
     */
    boolean hasStartColumn();
    /**
     * <code>optional int32 start_column = 2;</code>
     */
    int getStartColumn();

    /**
     * <code>optional int32 start_row = 3;</code>
     */
    boolean hasStartRow();
    /**
     * <code>optional int32 start_row = 3;</code>
     */
    int getStartRow();

    /**
     * <code>optional int32 end_column = 4;</code>
     */
    boolean hasEndColumn();
    /**
     * <code>optional int32 end_column = 4;</code>
     */
    int getEndColumn();

    /**
     * <code>optional int32 end_row = 5;</code>
     */
    boolean hasEndRow();
    /**
     * <code>optional int32 end_row = 5;</code>
     */
    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() {
      startColumn_ = 0;
      startRow_ = 0;
      endColumn_ = 0;
      endRow_ = 0;
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private ParsingError(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 16: {
              bitField0_ |= 0x00000001;
              startColumn_ = input.readInt32();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000002;
              startRow_ = input.readInt32();
              break;
            }
            case 32: {
              bitField0_ |= 0x00000004;
              endColumn_ = input.readInt32();
              break;
            }
            case 40: {
              bitField0_ |= 0x00000008;
              endRow_ = input.readInt32();
              break;
            }
            default: {
              if (!parseUnknownField(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.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>
     */
    public boolean hasStartColumn() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional int32 start_column = 2;</code>
     */
    public int getStartColumn() {
      return startColumn_;
    }

    public static final int START_ROW_FIELD_NUMBER = 3;
    private int startRow_;
    /**
     * <code>optional int32 start_row = 3;</code>
     */
    public boolean hasStartRow() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional int32 start_row = 3;</code>
     */
    public int getStartRow() {
      return startRow_;
    }

    public static final int END_COLUMN_FIELD_NUMBER = 4;
    private int endColumn_;
    /**
     * <code>optional int32 end_column = 4;</code>
     */
    public boolean hasEndColumn() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional int32 end_column = 4;</code>
     */
    public int getEndColumn() {
      return endColumn_;
    }

    public static final int END_ROW_FIELD_NUMBER = 5;
    private int endRow_;
    /**
     * <code>optional int32 end_row = 5;</code>
     */
    public boolean hasEndRow() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>optional int32 end_row = 5;</code>
     */
    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) == 0x00000001)) {
        output.writeInt32(2, startColumn_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt32(3, startRow_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeInt32(4, endColumn_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeInt32(5, endRow_);
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(2, startColumn_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(3, startRow_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(4, endColumn_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(5, endRow_);
      }
      size += unknownFields.getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.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;

      boolean result = true;
      result = result && (hasStartColumn() == other.hasStartColumn());
      if (hasStartColumn()) {
        result = result && (getStartColumn()
            == other.getStartColumn());
      }
      result = result && (hasStartRow() == other.hasStartRow());
      if (hasStartRow()) {
        result = result && (getStartRow()
            == other.getStartRow());
      }
      result = result && (hasEndColumn() == other.hasEndColumn());
      if (hasEndColumn()) {
        result = result && (getEndColumn()
            == other.getEndColumn());
      }
      result = result && (hasEndRow() == other.hasEndRow());
      if (hasEndRow()) {
        result = result && (getEndRow()
            == other.getEndRow());
      }
      result = result && unknownFields.equals(other.unknownFields);
      return result;
    }

    @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) + unknownFields.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() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        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) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.startColumn_ = startColumn_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.startRow_ = startRow_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.endColumn_ = endColumn_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.endRow_ = endRow_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return (Builder) super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return (Builder) super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return (Builder) super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return (Builder) super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) 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.unknownFields);
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.drill.exec.proto.UserBitShared.ParsingError parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.drill.exec.proto.UserBitShared.ParsingError) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private int startColumn_ ;
      /**
       * <code>optional int32 start_column = 2;</code>
       */
      public boolean hasStartColumn() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional int32 start_column = 2;</code>
       */
      public int getStartColumn() {
        return startColumn_;
      }
      /**
       * <code>optional int32 start_column = 2;</code>
       */
      public Builder setStartColumn(int value) {
        bitField0_ |= 0x00000001;
        startColumn_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 start_column = 2;</code>
       */
      public Builder clearStartColumn() {
        bitField0_ = (bitField0_ & ~0x00000001);
        startColumn_ = 0;
        onChanged();
        return this;
      }

      private int startRow_ ;
      /**
       * <code>optional int32 start_row = 3;</code>
       */
      public boolean hasStartRow() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional int32 start_row = 3;</code>
       */
      public int getStartRow() {
        return startRow_;
      }
      /**
       * <code>optional int32 start_row = 3;</code>
       */
      public Builder setStartRow(int value) {
        bitField0_ |= 0x00000002;
        startRow_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 start_row = 3;</code>
       */
      public Builder clearStartRow() {
        bitField0_ = (bitField0_ & ~0x00000002);
        startRow_ = 0;
        onChanged();
        return this;
      }

      private int endColumn_ ;
      /**
       * <code>optional int32 end_column = 4;</code>
       */
      public boolean hasEndColumn() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional int32 end_column = 4;</code>
       */
      public int getEndColumn() {
        return endColumn_;
      }
      /**
       * <code>optional int32 end_column = 4;</code>
       */
      public Builder setEndColumn(int value) {
        bitField0_ |= 0x00000004;
        endColumn_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 end_column = 4;</code>
       */
      public Builder clearEndColumn() {
        bitField0_ = (bitField0_ & ~0x00000004);
        endColumn_ = 0;
        onChanged();
        return this;
      }

      private int endRow_ ;
      /**
       * <code>optional int32 end_row = 5;</code>
       */
      public boolean hasEndRow() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>optional int32 end_row = 5;</code>
       */
      public int getEndRow() {
        return endRow_;
      }
      /**
       * <code>optional int32 end_row = 5;</code>
       */
      public Builder setEndRow(int value) {
        bitField0_ |= 0x00000008;
        endRow_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 end_row = 5;</code>
       */
      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 {
        return new ParsingError(input, extensionRegistry);
      }
    };

    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>
     */
    boolean hasRecordCount();
    /**
     * <code>optional int32 record_count = 1;</code>
     */
    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>
     */
    boolean hasCarriesTwoByteSelectionVector();
    /**
     * <code>optional bool carries_two_byte_selection_vector = 3;</code>
     */
    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>
     */
    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>
     */
    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() {
      recordCount_ = 0;
      field_ = java.util.Collections.emptyList();
      carriesTwoByteSelectionVector_ = false;
      affectedRowsCount_ = 0;
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private RecordBatchDef(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 8: {
              bitField0_ |= 0x00000001;
              recordCount_ = input.readInt32();
              break;
            }
            case 18: {
              if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
                field_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserBitShared.SerializedField>();
                mutable_bitField0_ |= 0x00000002;
              }
              field_.add(
                  input.readMessage(org.apache.drill.exec.proto.UserBitShared.SerializedField.PARSER, extensionRegistry));
              break;
            }
            case 24: {
              bitField0_ |= 0x00000002;
              carriesTwoByteSelectionVector_ = input.readBool();
              break;
            }
            case 32: {
              bitField0_ |= 0x00000004;
              affectedRowsCount_ = input.readInt32();
              break;
            }
            default: {
              if (!parseUnknownField(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
          field_ = java.util.Collections.unmodifiableList(field_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    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>
     */
    public boolean hasRecordCount() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional int32 record_count = 1;</code>
     */
    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>
     */
    public java.util.List<org.apache.drill.exec.proto.UserBitShared.SerializedField> getFieldList() {
      return field_;
    }
    /**
     * <code>repeated .exec.shared.SerializedField field = 2;</code>
     */
    public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.SerializedFieldOrBuilder> 
        getFieldOrBuilderList() {
      return field_;
    }
    /**
     * <code>repeated .exec.shared.SerializedField field = 2;</code>
     */
    public int getFieldCount() {
      return field_.size();
    }
    /**
     * <code>repeated .exec.shared.SerializedField field = 2;</code>
     */
    public org.apache.drill.exec.proto.UserBitShared.SerializedField getField(int index) {
      return field_.get(index);
    }
    /**
     * <code>repeated .exec.shared.SerializedField field = 2;</code>
     */
    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>
     */
    public boolean hasCarriesTwoByteSelectionVector() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional bool carries_two_byte_selection_vector = 3;</code>
     */
    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>
     */
    public boolean hasAffectedRowsCount() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <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>
     */
    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) == 0x00000001)) {
        output.writeInt32(1, recordCount_);
      }
      for (int i = 0; i < field_.size(); i++) {
        output.writeMessage(2, field_.get(i));
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBool(3, carriesTwoByteSelectionVector_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeInt32(4, affectedRowsCount_);
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        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) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(3, carriesTwoByteSelectionVector_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(4, affectedRowsCount_);
      }
      size += unknownFields.getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.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;

      boolean result = true;
      result = result && (hasRecordCount() == other.hasRecordCount());
      if (hasRecordCount()) {
        result = result && (getRecordCount()
            == other.getRecordCount());
      }
      result = result && getFieldList()
          .equals(other.getFieldList());
      result = result && (hasCarriesTwoByteSelectionVector() == other.hasCarriesTwoByteSelectionVector());
      if (hasCarriesTwoByteSelectionVector()) {
        result = result && (getCarriesTwoByteSelectionVector()
            == other.getCarriesTwoByteSelectionVector());
      }
      result = result && (hasAffectedRowsCount() == other.hasAffectedRowsCount());
      if (hasAffectedRowsCount()) {
        result = result && (getAffectedRowsCount()
            == other.getAffectedRowsCount());
      }
      result = result && unknownFields.equals(other.unknownFields);
      return result;
    }

    @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) + unknownFields.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() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getFieldFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        recordCount_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        if (fieldBuilder_ == null) {
          field_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000002);
        } else {
          fieldBuilder_.clear();
        }
        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) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.recordCount_ = recordCount_;
        if (fieldBuilder_ == null) {
          if (((bitField0_ & 0x00000002) == 0x00000002)) {
            field_ = java.util.Collections.unmodifiableList(field_);
            bitField0_ = (bitField0_ & ~0x00000002);
          }
          result.field_ = field_;
        } else {
          result.field_ = fieldBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000002;
        }
        result.carriesTwoByteSelectionVector_ = carriesTwoByteSelectionVector_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000004;
        }
        result.affectedRowsCount_ = affectedRowsCount_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return (Builder) super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return (Builder) super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return (Builder) super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return (Builder) super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) 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.unknownFields);
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.drill.exec.proto.UserBitShared.RecordBatchDef parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.drill.exec.proto.UserBitShared.RecordBatchDef) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private int recordCount_ ;
      /**
       * <code>optional int32 record_count = 1;</code>
       */
      public boolean hasRecordCount() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional int32 record_count = 1;</code>
       */
      public int getRecordCount() {
        return recordCount_;
      }
      /**
       * <code>optional int32 record_count = 1;</code>
       */
      public Builder setRecordCount(int value) {
        bitField0_ |= 0x00000001;
        recordCount_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 record_count = 1;</code>
       */
      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) == 0x00000002)) {
          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) == 0x00000002),
                  getParentForChildren(),
                  isClean());
          field_ = null;
        }
        return fieldBuilder_;
      }

      private boolean carriesTwoByteSelectionVector_ ;
      /**
       * <code>optional bool carries_two_byte_selection_vector = 3;</code>
       */
      public boolean hasCarriesTwoByteSelectionVector() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional bool carries_two_byte_selection_vector = 3;</code>
       */
      public boolean getCarriesTwoByteSelectionVector() {
        return carriesTwoByteSelectionVector_;
      }
      /**
       * <code>optional bool carries_two_byte_selection_vector = 3;</code>
       */
      public Builder setCarriesTwoByteSelectionVector(boolean value) {
        bitField0_ |= 0x00000004;
        carriesTwoByteSelectionVector_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool carries_two_byte_selection_vector = 3;</code>
       */
      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>
       */
      public boolean hasAffectedRowsCount() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <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>
       */
      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>
       */
      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>
       */
      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 {
        return new RecordBatchDef(input, extensionRegistry);
      }
    };

    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>
     */
    boolean hasType();
    /**
     * <code>optional .exec.shared.NamePart.Type type = 1;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.NamePart.Type getType();

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

    /**
     * <code>optional .exec.shared.NamePart child = 3;</code>
     */
    boolean hasChild();
    /**
     * <code>optional .exec.shared.NamePart child = 3;</code>
     */
    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
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private NamePart(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 8: {
              int rawValue = input.readEnum();
                @SuppressWarnings("deprecation")
              org.apache.drill.exec.proto.UserBitShared.NamePart.Type value = org.apache.drill.exec.proto.UserBitShared.NamePart.Type.valueOf(rawValue);
              if (value == null) {
                unknownFields.mergeVarintField(1, rawValue);
              } else {
                bitField0_ |= 0x00000001;
                type_ = rawValue;
              }
              break;
            }
            case 18: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00000002;
              name_ = bs;
              break;
            }
            case 26: {
              org.apache.drill.exec.proto.UserBitShared.NamePart.Builder subBuilder = null;
              if (((bitField0_ & 0x00000004) == 0x00000004)) {
                subBuilder = child_.toBuilder();
              }
              child_ = input.readMessage(org.apache.drill.exec.proto.UserBitShared.NamePart.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(child_);
                child_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000004;
              break;
            }
            default: {
              if (!parseUnknownField(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.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;
      }

      /**
       * @deprecated Use {@link #forNumber(int)} instead.
       */
      @java.lang.Deprecated
      public static Type valueOf(int value) {
        return forNumber(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>
     */
    public boolean hasType() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional .exec.shared.NamePart.Type type = 1;</code>
     */
    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>
     */
    public boolean hasName() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional string name = 2;</code>
     */
    public java.lang.String getName() {
      java.lang.Object ref = name_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          name_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string name = 2;</code>
     */
    public com.google.protobuf.ByteString
        getNameBytes() {
      java.lang.Object ref = name_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        name_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int CHILD_FIELD_NUMBER = 3;
    private org.apache.drill.exec.proto.UserBitShared.NamePart child_;
    /**
     * <code>optional .exec.shared.NamePart child = 3;</code>
     */
    public boolean hasChild() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional .exec.shared.NamePart child = 3;</code>
     */
    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>
     */
    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) == 0x00000001)) {
        output.writeEnum(1, type_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, name_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeMessage(3, getChild());
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(1, type_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, name_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, getChild());
      }
      size += unknownFields.getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.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;

      boolean result = true;
      result = result && (hasType() == other.hasType());
      if (hasType()) {
        result = result && type_ == other.type_;
      }
      result = result && (hasName() == other.hasName());
      if (hasName()) {
        result = result && getName()
            .equals(other.getName());
      }
      result = result && (hasChild() == other.hasChild());
      if (hasChild()) {
        result = result && getChild()
            .equals(other.getChild());
      }
      result = result && unknownFields.equals(other.unknownFields);
      return result;
    }

    @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) + unknownFields.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) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.type_ = type_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.name_ = name_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        if (childBuilder_ == null) {
          result.child_ = child_;
        } else {
          result.child_ = childBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return (Builder) super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return (Builder) super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return (Builder) super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return (Builder) super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) 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.unknownFields);
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.drill.exec.proto.UserBitShared.NamePart parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.drill.exec.proto.UserBitShared.NamePart) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private int type_ = 0;
      /**
       * <code>optional .exec.shared.NamePart.Type type = 1;</code>
       */
      public boolean hasType() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional .exec.shared.NamePart.Type type = 1;</code>
       */
      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>
       */
      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>
       */
      public Builder clearType() {
        bitField0_ = (bitField0_ & ~0x00000001);
        type_ = 0;
        onChanged();
        return this;
      }

      private java.lang.Object name_ = "";
      /**
       * <code>optional string name = 2;</code>
       */
      public boolean hasName() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional string name = 2;</code>
       */
      public java.lang.String getName() {
        java.lang.Object ref = name_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            name_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string name = 2;</code>
       */
      public com.google.protobuf.ByteString
          getNameBytes() {
        java.lang.Object ref = name_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          name_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string name = 2;</code>
       */
      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>
       */
      public Builder clearName() {
        bitField0_ = (bitField0_ & ~0x00000002);
        name_ = getDefaultInstance().getName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string name = 2;</code>
       */
      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_ = null;
      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>
       */
      public boolean hasChild() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional .exec.shared.NamePart child = 3;</code>
       */
      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) == 0x00000004) &&
              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 {
        return new NamePart(input, extensionRegistry);
      }
    };

    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>
     */
    boolean hasMajorType();
    /**
     * <pre>
     * the type associated with this field.
     * </pre>
     *
     * <code>optional .common.MajorType major_type = 1;</code>
     */
    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>
     */
    boolean hasNamePart();
    /**
     * <code>optional .exec.shared.NamePart name_part = 2;</code>
     */
    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>
     */
    boolean hasValueCount();
    /**
     * <code>optional int32 value_count = 4;</code>
     */
    int getValueCount();

    /**
     * <code>optional int32 var_byte_length = 5;</code>
     */
    boolean hasVarByteLength();
    /**
     * <code>optional int32 var_byte_length = 5;</code>
     */
    int getVarByteLength();

    /**
     * <code>optional int32 buffer_length = 7;</code>
     */
    boolean hasBufferLength();
    /**
     * <code>optional int32 buffer_length = 7;</code>
     */
    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();
      valueCount_ = 0;
      varByteLength_ = 0;
      bufferLength_ = 0;
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private SerializedField(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 10: {
              org.apache.drill.common.types.TypeProtos.MajorType.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = majorType_.toBuilder();
              }
              majorType_ = input.readMessage(org.apache.drill.common.types.TypeProtos.MajorType.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(majorType_);
                majorType_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 18: {
              org.apache.drill.exec.proto.UserBitShared.NamePart.Builder subBuilder = null;
              if (((bitField0_ & 0x00000002) == 0x00000002)) {
                subBuilder = namePart_.toBuilder();
              }
              namePart_ = input.readMessage(org.apache.drill.exec.proto.UserBitShared.NamePart.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(namePart_);
                namePart_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000002;
              break;
            }
            case 26: {
              if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
                child_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserBitShared.SerializedField>();
                mutable_bitField0_ |= 0x00000004;
              }
              child_.add(
                  input.readMessage(org.apache.drill.exec.proto.UserBitShared.SerializedField.PARSER, extensionRegistry));
              break;
            }
            case 32: {
              bitField0_ |= 0x00000004;
              valueCount_ = input.readInt32();
              break;
            }
            case 40: {
              bitField0_ |= 0x00000008;
              varByteLength_ = input.readInt32();
              break;
            }
            case 56: {
              bitField0_ |= 0x00000010;
              bufferLength_ = input.readInt32();
              break;
            }
            default: {
              if (!parseUnknownField(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
          child_ = java.util.Collections.unmodifiableList(child_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    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>
     */
    public boolean hasMajorType() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <pre>
     * the type associated with this field.
     * </pre>
     *
     * <code>optional .common.MajorType major_type = 1;</code>
     */
    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>
     */
    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>
     */
    public boolean hasNamePart() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional .exec.shared.NamePart name_part = 2;</code>
     */
    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>
     */
    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>
     */
    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>
     */
    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>
     */
    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>
     */
    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>
     */
    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>
     */
    public boolean hasValueCount() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional int32 value_count = 4;</code>
     */
    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>
     */
    public boolean hasVarByteLength() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>optional int32 var_byte_length = 5;</code>
     */
    public int getVarByteLength() {
      return varByteLength_;
    }

    public static final int BUFFER_LENGTH_FIELD_NUMBER = 7;
    private int bufferLength_;
    /**
     * <code>optional int32 buffer_length = 7;</code>
     */
    public boolean hasBufferLength() {
      return ((bitField0_ & 0x00000010) == 0x00000010);
    }
    /**
     * <code>optional int32 buffer_length = 7;</code>
     */
    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) == 0x00000001)) {
        output.writeMessage(1, getMajorType());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeMessage(2, getNamePart());
      }
      for (int i = 0; i < child_.size(); i++) {
        output.writeMessage(3, child_.get(i));
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeInt32(4, valueCount_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeInt32(5, varByteLength_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        output.writeInt32(7, bufferLength_);
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, getMajorType());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        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) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(4, valueCount_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(5, varByteLength_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(7, bufferLength_);
      }
      size += unknownFields.getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.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;

      boolean result = true;
      result = result && (hasMajorType() == other.hasMajorType());
      if (hasMajorType()) {
        result = result && getMajorType()
            .equals(other.getMajorType());
      }
      result = result && (hasNamePart() == other.hasNamePart());
      if (hasNamePart()) {
        result = result && getNamePart()
            .equals(other.getNamePart());
      }
      result = result && getChildList()
          .equals(other.getChildList());
      result = result && (hasValueCount() == other.hasValueCount());
      if (hasValueCount()) {
        result = result && (getValueCount()
            == other.getValueCount());
      }
      result = result && (hasVarByteLength() == other.hasVarByteLength());
      if (hasVarByteLength()) {
        result = result && (getVarByteLength()
            == other.getVarByteLength());
      }
      result = result && (hasBufferLength() == other.hasBufferLength());
      if (hasBufferLength()) {
        result = result && (getBufferLength()
            == other.getBufferLength());
      }
      result = result && unknownFields.equals(other.unknownFields);
      return result;
    }

    @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) + unknownFields.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();
          bitField0_ = (bitField0_ & ~0x00000004);
        } else {
          childBuilder_.clear();
        }
        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) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (majorTypeBuilder_ == null) {
          result.majorType_ = majorType_;
        } else {
          result.majorType_ = majorTypeBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        if (namePartBuilder_ == null) {
          result.namePart_ = namePart_;
        } else {
          result.namePart_ = namePartBuilder_.build();
        }
        if (childBuilder_ == null) {
          if (((bitField0_ & 0x00000004) == 0x00000004)) {
            child_ = java.util.Collections.unmodifiableList(child_);
            bitField0_ = (bitField0_ & ~0x00000004);
          }
          result.child_ = child_;
        } else {
          result.child_ = childBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000004;
        }
        result.valueCount_ = valueCount_;
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000008;
        }
        result.varByteLength_ = varByteLength_;
        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
          to_bitField0_ |= 0x00000010;
        }
        result.bufferLength_ = bufferLength_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return (Builder) super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return (Builder) super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return (Builder) super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return (Builder) super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) 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.unknownFields);
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.drill.exec.proto.UserBitShared.SerializedField parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.drill.exec.proto.UserBitShared.SerializedField) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private org.apache.drill.common.types.TypeProtos.MajorType majorType_ = null;
      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>
       */
      public boolean hasMajorType() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <pre>
       * the type associated with this field.
       * </pre>
       *
       * <code>optional .common.MajorType major_type = 1;</code>
       */
      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) == 0x00000001) &&
              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_ = null;
      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>
       */
      public boolean hasNamePart() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional .exec.shared.NamePart name_part = 2;</code>
       */
      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) == 0x00000002) &&
              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) == 0x00000004)) {
          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) == 0x00000004),
                  getParentForChildren(),
                  isClean());
          child_ = null;
        }
        return childBuilder_;
      }

      private int valueCount_ ;
      /**
       * <code>optional int32 value_count = 4;</code>
       */
      public boolean hasValueCount() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>optional int32 value_count = 4;</code>
       */
      public int getValueCount() {
        return valueCount_;
      }
      /**
       * <code>optional int32 value_count = 4;</code>
       */
      public Builder setValueCount(int value) {
        bitField0_ |= 0x00000008;
        valueCount_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 value_count = 4;</code>
       */
      public Builder clearValueCount() {
        bitField0_ = (bitField0_ & ~0x00000008);
        valueCount_ = 0;
        onChanged();
        return this;
      }

      private int varByteLength_ ;
      /**
       * <code>optional int32 var_byte_length = 5;</code>
       */
      public boolean hasVarByteLength() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      /**
       * <code>optional int32 var_byte_length = 5;</code>
       */
      public int getVarByteLength() {
        return varByteLength_;
      }
      /**
       * <code>optional int32 var_byte_length = 5;</code>
       */
      public Builder setVarByteLength(int value) {
        bitField0_ |= 0x00000010;
        varByteLength_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 var_byte_length = 5;</code>
       */
      public Builder clearVarByteLength() {
        bitField0_ = (bitField0_ & ~0x00000010);
        varByteLength_ = 0;
        onChanged();
        return this;
      }

      private int bufferLength_ ;
      /**
       * <code>optional int32 buffer_length = 7;</code>
       */
      public boolean hasBufferLength() {
        return ((bitField0_ & 0x00000020) == 0x00000020);
      }
      /**
       * <code>optional int32 buffer_length = 7;</code>
       */
      public int getBufferLength() {
        return bufferLength_;
      }
      /**
       * <code>optional int32 buffer_length = 7;</code>
       */
      public Builder setBufferLength(int value) {
        bitField0_ |= 0x00000020;
        bufferLength_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 buffer_length = 7;</code>
       */
      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 {
        return new SerializedField(input, extensionRegistry);
      }
    };

    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>
     */
    boolean hasNodeId();
    /**
     * <code>optional int32 node_id = 1;</code>
     */
    int getNodeId();

    /**
     * <code>optional int64 memory_footprint = 2;</code>
     */
    boolean hasMemoryFootprint();
    /**
     * <code>optional int64 memory_footprint = 2;</code>
     */
    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() {
      nodeId_ = 0;
      memoryFootprint_ = 0L;
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private NodeStatus(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 8: {
              bitField0_ |= 0x00000001;
              nodeId_ = input.readInt32();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              memoryFootprint_ = input.readInt64();
              break;
            }
            default: {
              if (!parseUnknownField(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.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>
     */
    public boolean hasNodeId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional int32 node_id = 1;</code>
     */
    public int getNodeId() {
      return nodeId_;
    }

    public static final int MEMORY_FOOTPRINT_FIELD_NUMBER = 2;
    private long memoryFootprint_;
    /**
     * <code>optional int64 memory_footprint = 2;</code>
     */
    public boolean hasMemoryFootprint() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional int64 memory_footprint = 2;</code>
     */
    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) == 0x00000001)) {
        output.writeInt32(1, nodeId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt64(2, memoryFootprint_);
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(1, nodeId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, memoryFootprint_);
      }
      size += unknownFields.getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.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;

      boolean result = true;
      result = result && (hasNodeId() == other.hasNodeId());
      if (hasNodeId()) {
        result = result && (getNodeId()
            == other.getNodeId());
      }
      result = result && (hasMemoryFootprint() == other.hasMemoryFootprint());
      if (hasMemoryFootprint()) {
        result = result && (getMemoryFootprint()
            == other.getMemoryFootprint());
      }
      result = result && unknownFields.equals(other.unknownFields);
      return result;
    }

    @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) + unknownFields.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() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        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) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.nodeId_ = nodeId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.memoryFootprint_ = memoryFootprint_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return (Builder) super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return (Builder) super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return (Builder) super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return (Builder) super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) 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.unknownFields);
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.drill.exec.proto.UserBitShared.NodeStatus parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.drill.exec.proto.UserBitShared.NodeStatus) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private int nodeId_ ;
      /**
       * <code>optional int32 node_id = 1;</code>
       */
      public boolean hasNodeId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional int32 node_id = 1;</code>
       */
      public int getNodeId() {
        return nodeId_;
      }
      /**
       * <code>optional int32 node_id = 1;</code>
       */
      public Builder setNodeId(int value) {
        bitField0_ |= 0x00000001;
        nodeId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 node_id = 1;</code>
       */
      public Builder clearNodeId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        nodeId_ = 0;
        onChanged();
        return this;
      }

      private long memoryFootprint_ ;
      /**
       * <code>optional int64 memory_footprint = 2;</code>
       */
      public boolean hasMemoryFootprint() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional int64 memory_footprint = 2;</code>
       */
      public long getMemoryFootprint() {
        return memoryFootprint_;
      }
      /**
       * <code>optional int64 memory_footprint = 2;</code>
       */
      public Builder setMemoryFootprint(long value) {
        bitField0_ |= 0x00000002;
        memoryFootprint_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 memory_footprint = 2;</code>
       */
      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 {
        return new NodeStatus(input, extensionRegistry);
      }
    };

    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>
     */
    boolean hasQueryState();
    /**
     * <code>optional .exec.shared.QueryResult.QueryState query_state = 1;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState getQueryState();

    /**
     * <code>optional .exec.shared.QueryId query_id = 2;</code>
     */
    boolean hasQueryId();
    /**
     * <code>optional .exec.shared.QueryId query_id = 2;</code>
     */
    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
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private QueryResult(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 8: {
              int rawValue = input.readEnum();
                @SuppressWarnings("deprecation")
              org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState value = org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.valueOf(rawValue);
              if (value == null) {
                unknownFields.mergeVarintField(1, rawValue);
              } else {
                bitField0_ |= 0x00000001;
                queryState_ = rawValue;
              }
              break;
            }
            case 18: {
              org.apache.drill.exec.proto.UserBitShared.QueryId.Builder subBuilder = null;
              if (((bitField0_ & 0x00000002) == 0x00000002)) {
                subBuilder = queryId_.toBuilder();
              }
              queryId_ = input.readMessage(org.apache.drill.exec.proto.UserBitShared.QueryId.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(queryId_);
                queryId_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000002;
              break;
            }
            case 26: {
              if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
                error_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserBitShared.DrillPBError>();
                mutable_bitField0_ |= 0x00000004;
              }
              error_.add(
                  input.readMessage(org.apache.drill.exec.proto.UserBitShared.DrillPBError.PARSER, extensionRegistry));
              break;
            }
            default: {
              if (!parseUnknownField(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
          error_ = java.util.Collections.unmodifiableList(error_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    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;
      }

      /**
       * @deprecated Use {@link #forNumber(int)} instead.
       */
      @java.lang.Deprecated
      public static QueryState valueOf(int value) {
        return forNumber(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>
     */
    public boolean hasQueryState() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional .exec.shared.QueryResult.QueryState query_state = 1;</code>
     */
    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>
     */
    public boolean hasQueryId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional .exec.shared.QueryId query_id = 2;</code>
     */
    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>
     */
    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>
     */
    public java.util.List<org.apache.drill.exec.proto.UserBitShared.DrillPBError> getErrorList() {
      return error_;
    }
    /**
     * <code>repeated .exec.shared.DrillPBError error = 3;</code>
     */
    public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder> 
        getErrorOrBuilderList() {
      return error_;
    }
    /**
     * <code>repeated .exec.shared.DrillPBError error = 3;</code>
     */
    public int getErrorCount() {
      return error_.size();
    }
    /**
     * <code>repeated .exec.shared.DrillPBError error = 3;</code>
     */
    public org.apache.drill.exec.proto.UserBitShared.DrillPBError getError(int index) {
      return error_.get(index);
    }
    /**
     * <code>repeated .exec.shared.DrillPBError error = 3;</code>
     */
    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) == 0x00000001)) {
        output.writeEnum(1, queryState_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeMessage(2, getQueryId());
      }
      for (int i = 0; i < error_.size(); i++) {
        output.writeMessage(3, error_.get(i));
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(1, queryState_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        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 += unknownFields.getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.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;

      boolean result = true;
      result = result && (hasQueryState() == other.hasQueryState());
      if (hasQueryState()) {
        result = result && queryState_ == other.queryState_;
      }
      result = result && (hasQueryId() == other.hasQueryId());
      if (hasQueryId()) {
        result = result && getQueryId()
            .equals(other.getQueryId());
      }
      result = result && getErrorList()
          .equals(other.getErrorList());
      result = result && unknownFields.equals(other.unknownFields);
      return result;
    }

    @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) + unknownFields.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();
          bitField0_ = (bitField0_ & ~0x00000004);
        } else {
          errorBuilder_.clear();
        }
        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) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.queryState_ = queryState_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        if (queryIdBuilder_ == null) {
          result.queryId_ = queryId_;
        } else {
          result.queryId_ = queryIdBuilder_.build();
        }
        if (errorBuilder_ == null) {
          if (((bitField0_ & 0x00000004) == 0x00000004)) {
            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 (Builder) super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return (Builder) super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return (Builder) super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return (Builder) super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) 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.unknownFields);
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.drill.exec.proto.UserBitShared.QueryResult parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.drill.exec.proto.UserBitShared.QueryResult) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private int queryState_ = 0;
      /**
       * <code>optional .exec.shared.QueryResult.QueryState query_state = 1;</code>
       */
      public boolean hasQueryState() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional .exec.shared.QueryResult.QueryState query_state = 1;</code>
       */
      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>
       */
      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>
       */
      public Builder clearQueryState() {
        bitField0_ = (bitField0_ & ~0x00000001);
        queryState_ = 0;
        onChanged();
        return this;
      }

      private org.apache.drill.exec.proto.UserBitShared.QueryId queryId_ = null;
      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>
       */
      public boolean hasQueryId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 2;</code>
       */
      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) == 0x00000002) &&
              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) == 0x00000004)) {
          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) == 0x00000004),
                  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 {
        return new QueryResult(input, extensionRegistry);
      }
    };

    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>
     */
    boolean hasQueryId();
    /**
     * <code>optional .exec.shared.QueryId query_id = 1;</code>
     */
    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>
     */
    boolean hasRowCount();
    /**
     * <code>optional int32 row_count = 2;</code>
     */
    int getRowCount();

    /**
     * <code>optional .exec.shared.RecordBatchDef def = 3;</code>
     */
    boolean hasDef();
    /**
     * <code>optional .exec.shared.RecordBatchDef def = 3;</code>
     */
    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>
     */
    boolean hasAffectedRowsCount();
    /**
     * <code>optional int32 affected_rows_count = 4;</code>
     */
    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() {
      rowCount_ = 0;
      affectedRowsCount_ = 0;
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private QueryData(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 10: {
              org.apache.drill.exec.proto.UserBitShared.QueryId.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = queryId_.toBuilder();
              }
              queryId_ = input.readMessage(org.apache.drill.exec.proto.UserBitShared.QueryId.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(queryId_);
                queryId_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              rowCount_ = input.readInt32();
              break;
            }
            case 26: {
              org.apache.drill.exec.proto.UserBitShared.RecordBatchDef.Builder subBuilder = null;
              if (((bitField0_ & 0x00000004) == 0x00000004)) {
                subBuilder = def_.toBuilder();
              }
              def_ = input.readMessage(org.apache.drill.exec.proto.UserBitShared.RecordBatchDef.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(def_);
                def_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000004;
              break;
            }
            case 32: {
              bitField0_ |= 0x00000008;
              affectedRowsCount_ = input.readInt32();
              break;
            }
            default: {
              if (!parseUnknownField(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.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>
     */
    public boolean hasQueryId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional .exec.shared.QueryId query_id = 1;</code>
     */
    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>
     */
    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>
     */
    public boolean hasRowCount() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional int32 row_count = 2;</code>
     */
    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>
     */
    public boolean hasDef() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional .exec.shared.RecordBatchDef def = 3;</code>
     */
    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>
     */
    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>
     */
    public boolean hasAffectedRowsCount() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>optional int32 affected_rows_count = 4;</code>
     */
    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) == 0x00000001)) {
        output.writeMessage(1, getQueryId());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt32(2, rowCount_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeMessage(3, getDef());
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeInt32(4, affectedRowsCount_);
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, getQueryId());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(2, rowCount_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, getDef());
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(4, affectedRowsCount_);
      }
      size += unknownFields.getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.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;

      boolean result = true;
      result = result && (hasQueryId() == other.hasQueryId());
      if (hasQueryId()) {
        result = result && getQueryId()
            .equals(other.getQueryId());
      }
      result = result && (hasRowCount() == other.hasRowCount());
      if (hasRowCount()) {
        result = result && (getRowCount()
            == other.getRowCount());
      }
      result = result && (hasDef() == other.hasDef());
      if (hasDef()) {
        result = result && getDef()
            .equals(other.getDef());
      }
      result = result && (hasAffectedRowsCount() == other.hasAffectedRowsCount());
      if (hasAffectedRowsCount()) {
        result = result && (getAffectedRowsCount()
            == other.getAffectedRowsCount());
      }
      result = result && unknownFields.equals(other.unknownFields);
      return result;
    }

    @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) + unknownFields.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) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (queryIdBuilder_ == null) {
          result.queryId_ = queryId_;
        } else {
          result.queryId_ = queryIdBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.rowCount_ = rowCount_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        if (defBuilder_ == null) {
          result.def_ = def_;
        } else {
          result.def_ = defBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.affectedRowsCount_ = affectedRowsCount_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return (Builder) super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return (Builder) super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return (Builder) super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return (Builder) super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) 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.unknownFields);
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.drill.exec.proto.UserBitShared.QueryData parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.drill.exec.proto.UserBitShared.QueryData) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private org.apache.drill.exec.proto.UserBitShared.QueryId queryId_ = null;
      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>
       */
      public boolean hasQueryId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 1;</code>
       */
      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) == 0x00000001) &&
              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>
       */
      public boolean hasRowCount() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional int32 row_count = 2;</code>
       */
      public int getRowCount() {
        return rowCount_;
      }
      /**
       * <code>optional int32 row_count = 2;</code>
       */
      public Builder setRowCount(int value) {
        bitField0_ |= 0x00000002;
        rowCount_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 row_count = 2;</code>
       */
      public Builder clearRowCount() {
        bitField0_ = (bitField0_ & ~0x00000002);
        rowCount_ = 0;
        onChanged();
        return this;
      }

      private org.apache.drill.exec.proto.UserBitShared.RecordBatchDef def_ = null;
      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>
       */
      public boolean hasDef() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional .exec.shared.RecordBatchDef def = 3;</code>
       */
      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) == 0x00000004) &&
              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>
       */
      public boolean hasAffectedRowsCount() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>optional int32 affected_rows_count = 4;</code>
       */
      public int getAffectedRowsCount() {
        return affectedRowsCount_;
      }
      /**
       * <code>optional int32 affected_rows_count = 4;</code>
       */
      public Builder setAffectedRowsCount(int value) {
        bitField0_ |= 0x00000008;
        affectedRowsCount_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 affected_rows_count = 4;</code>
       */
      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 {
        return new QueryData(input, extensionRegistry);
      }
    };

    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>
     */
    boolean hasQuery();
    /**
     * <code>optional string query = 1;</code>
     */
    java.lang.String getQuery();
    /**
     * <code>optional string query = 1;</code>
     */
    com.google.protobuf.ByteString
        getQueryBytes();

    /**
     * <code>optional int64 start = 2;</code>
     */
    boolean hasStart();
    /**
     * <code>optional int64 start = 2;</code>
     */
    long getStart();

    /**
     * <code>optional .exec.shared.QueryResult.QueryState state = 3;</code>
     */
    boolean hasState();
    /**
     * <code>optional .exec.shared.QueryResult.QueryState state = 3;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState getState();

    /**
     * <code>optional string user = 4 [default = "-"];</code>
     */
    boolean hasUser();
    /**
     * <code>optional string user = 4 [default = "-"];</code>
     */
    java.lang.String getUser();
    /**
     * <code>optional string user = 4 [default = "-"];</code>
     */
    com.google.protobuf.ByteString
        getUserBytes();

    /**
     * <code>optional .exec.DrillbitEndpoint foreman = 5;</code>
     */
    boolean hasForeman();
    /**
     * <code>optional .exec.DrillbitEndpoint foreman = 5;</code>
     */
    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>
     */
    boolean hasOptionsJson();
    /**
     * <code>optional string options_json = 6;</code>
     */
    java.lang.String getOptionsJson();
    /**
     * <code>optional string options_json = 6;</code>
     */
    com.google.protobuf.ByteString
        getOptionsJsonBytes();

    /**
     * <code>optional double total_cost = 7;</code>
     */
    boolean hasTotalCost();
    /**
     * <code>optional double total_cost = 7;</code>
     */
    double getTotalCost();

    /**
     * <code>optional string queue_name = 8 [default = "-"];</code>
     */
    boolean hasQueueName();
    /**
     * <code>optional string queue_name = 8 [default = "-"];</code>
     */
    java.lang.String getQueueName();
    /**
     * <code>optional string queue_name = 8 [default = "-"];</code>
     */
    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_ = "";
      start_ = 0L;
      state_ = 0;
      user_ = "-";
      optionsJson_ = "";
      totalCost_ = 0D;
      queueName_ = "-";
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private QueryInfo(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 10: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00000001;
              query_ = bs;
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              start_ = input.readInt64();
              break;
            }
            case 24: {
              int rawValue = input.readEnum();
                @SuppressWarnings("deprecation")
              org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState value = org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.valueOf(rawValue);
              if (value == null) {
                unknownFields.mergeVarintField(3, rawValue);
              } else {
                bitField0_ |= 0x00000004;
                state_ = rawValue;
              }
              break;
            }
            case 34: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00000008;
              user_ = bs;
              break;
            }
            case 42: {
              org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder subBuilder = null;
              if (((bitField0_ & 0x00000010) == 0x00000010)) {
                subBuilder = foreman_.toBuilder();
              }
              foreman_ = input.readMessage(org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(foreman_);
                foreman_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000010;
              break;
            }
            case 50: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00000020;
              optionsJson_ = bs;
              break;
            }
            case 57: {
              bitField0_ |= 0x00000040;
              totalCost_ = input.readDouble();
              break;
            }
            case 66: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00000080;
              queueName_ = bs;
              break;
            }
            default: {
              if (!parseUnknownField(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.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>
     */
    public boolean hasQuery() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional string query = 1;</code>
     */
    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>
     */
    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>
     */
    public boolean hasStart() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional int64 start = 2;</code>
     */
    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>
     */
    public boolean hasState() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional .exec.shared.QueryResult.QueryState state = 3;</code>
     */
    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>
     */
    public boolean hasUser() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>optional string user = 4 [default = "-"];</code>
     */
    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>
     */
    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>
     */
    public boolean hasForeman() {
      return ((bitField0_ & 0x00000010) == 0x00000010);
    }
    /**
     * <code>optional .exec.DrillbitEndpoint foreman = 5;</code>
     */
    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>
     */
    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>
     */
    public boolean hasOptionsJson() {
      return ((bitField0_ & 0x00000020) == 0x00000020);
    }
    /**
     * <code>optional string options_json = 6;</code>
     */
    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>
     */
    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>
     */
    public boolean hasTotalCost() {
      return ((bitField0_ & 0x00000040) == 0x00000040);
    }
    /**
     * <code>optional double total_cost = 7;</code>
     */
    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>
     */
    public boolean hasQueueName() {
      return ((bitField0_ & 0x00000080) == 0x00000080);
    }
    /**
     * <code>optional string queue_name = 8 [default = "-"];</code>
     */
    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>
     */
    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) == 0x00000001)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, query_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt64(2, start_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeEnum(3, state_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 4, user_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        output.writeMessage(5, getForeman());
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 6, optionsJson_);
      }
      if (((bitField0_ & 0x00000040) == 0x00000040)) {
        output.writeDouble(7, totalCost_);
      }
      if (((bitField0_ & 0x00000080) == 0x00000080)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 8, queueName_);
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, query_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, start_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(3, state_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, user_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(5, getForeman());
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, optionsJson_);
      }
      if (((bitField0_ & 0x00000040) == 0x00000040)) {
        size += com.google.protobuf.CodedOutputStream
          .computeDoubleSize(7, totalCost_);
      }
      if (((bitField0_ & 0x00000080) == 0x00000080)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(8, queueName_);
      }
      size += unknownFields.getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.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;

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

    @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) + unknownFields.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) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.query_ = query_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.start_ = start_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.state_ = state_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.user_ = user_;
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000010;
        }
        if (foremanBuilder_ == null) {
          result.foreman_ = foreman_;
        } else {
          result.foreman_ = foremanBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
          to_bitField0_ |= 0x00000020;
        }
        result.optionsJson_ = optionsJson_;
        if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
          to_bitField0_ |= 0x00000040;
        }
        result.totalCost_ = totalCost_;
        if (((from_bitField0_ & 0x00000080) == 0x00000080)) {
          to_bitField0_ |= 0x00000080;
        }
        result.queueName_ = queueName_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return (Builder) super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return (Builder) super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return (Builder) super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return (Builder) super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) 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.unknownFields);
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.drill.exec.proto.UserBitShared.QueryInfo parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.drill.exec.proto.UserBitShared.QueryInfo) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private java.lang.Object query_ = "";
      /**
       * <code>optional string query = 1;</code>
       */
      public boolean hasQuery() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional string query = 1;</code>
       */
      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>
       */
      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>
       */
      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>
       */
      public Builder clearQuery() {
        bitField0_ = (bitField0_ & ~0x00000001);
        query_ = getDefaultInstance().getQuery();
        onChanged();
        return this;
      }
      /**
       * <code>optional string query = 1;</code>
       */
      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>
       */
      public boolean hasStart() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional int64 start = 2;</code>
       */
      public long getStart() {
        return start_;
      }
      /**
       * <code>optional int64 start = 2;</code>
       */
      public Builder setStart(long value) {
        bitField0_ |= 0x00000002;
        start_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 start = 2;</code>
       */
      public Builder clearStart() {
        bitField0_ = (bitField0_ & ~0x00000002);
        start_ = 0L;
        onChanged();
        return this;
      }

      private int state_ = 0;
      /**
       * <code>optional .exec.shared.QueryResult.QueryState state = 3;</code>
       */
      public boolean hasState() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional .exec.shared.QueryResult.QueryState state = 3;</code>
       */
      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>
       */
      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>
       */
      public Builder clearState() {
        bitField0_ = (bitField0_ & ~0x00000004);
        state_ = 0;
        onChanged();
        return this;
      }

      private java.lang.Object user_ = "-";
      /**
       * <code>optional string user = 4 [default = "-"];</code>
       */
      public boolean hasUser() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>optional string user = 4 [default = "-"];</code>
       */
      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>
       */
      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>
       */
      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>
       */
      public Builder clearUser() {
        bitField0_ = (bitField0_ & ~0x00000008);
        user_ = getDefaultInstance().getUser();
        onChanged();
        return this;
      }
      /**
       * <code>optional string user = 4 [default = "-"];</code>
       */
      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_ = null;
      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>
       */
      public boolean hasForeman() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      /**
       * <code>optional .exec.DrillbitEndpoint foreman = 5;</code>
       */
      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) == 0x00000010) &&
              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>
       */
      public boolean hasOptionsJson() {
        return ((bitField0_ & 0x00000020) == 0x00000020);
      }
      /**
       * <code>optional string options_json = 6;</code>
       */
      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>
       */
      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>
       */
      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>
       */
      public Builder clearOptionsJson() {
        bitField0_ = (bitField0_ & ~0x00000020);
        optionsJson_ = getDefaultInstance().getOptionsJson();
        onChanged();
        return this;
      }
      /**
       * <code>optional string options_json = 6;</code>
       */
      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>
       */
      public boolean hasTotalCost() {
        return ((bitField0_ & 0x00000040) == 0x00000040);
      }
      /**
       * <code>optional double total_cost = 7;</code>
       */
      public double getTotalCost() {
        return totalCost_;
      }
      /**
       * <code>optional double total_cost = 7;</code>
       */
      public Builder setTotalCost(double value) {
        bitField0_ |= 0x00000040;
        totalCost_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional double total_cost = 7;</code>
       */
      public Builder clearTotalCost() {
        bitField0_ = (bitField0_ & ~0x00000040);
        totalCost_ = 0D;
        onChanged();
        return this;
      }

      private java.lang.Object queueName_ = "-";
      /**
       * <code>optional string queue_name = 8 [default = "-"];</code>
       */
      public boolean hasQueueName() {
        return ((bitField0_ & 0x00000080) == 0x00000080);
      }
      /**
       * <code>optional string queue_name = 8 [default = "-"];</code>
       */
      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>
       */
      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>
       */
      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>
       */
      public Builder clearQueueName() {
        bitField0_ = (bitField0_ & ~0x00000080);
        queueName_ = getDefaultInstance().getQueueName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string queue_name = 8 [default = "-"];</code>
       */
      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 {
        return new QueryInfo(input, extensionRegistry);
      }
    };

    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>
     */
    boolean hasId();
    /**
     * <code>optional .exec.shared.QueryId id = 1;</code>
     */
    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>
     */
    boolean hasType();
    /**
     * <code>optional .exec.shared.QueryType type = 2;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.QueryType getType();

    /**
     * <code>optional int64 start = 3;</code>
     */
    boolean hasStart();
    /**
     * <code>optional int64 start = 3;</code>
     */
    long getStart();

    /**
     * <code>optional int64 end = 4;</code>
     */
    boolean hasEnd();
    /**
     * <code>optional int64 end = 4;</code>
     */
    long getEnd();

    /**
     * <code>optional string query = 5;</code>
     */
    boolean hasQuery();
    /**
     * <code>optional string query = 5;</code>
     */
    java.lang.String getQuery();
    /**
     * <code>optional string query = 5;</code>
     */
    com.google.protobuf.ByteString
        getQueryBytes();

    /**
     * <code>optional string plan = 6;</code>
     */
    boolean hasPlan();
    /**
     * <code>optional string plan = 6;</code>
     */
    java.lang.String getPlan();
    /**
     * <code>optional string plan = 6;</code>
     */
    com.google.protobuf.ByteString
        getPlanBytes();

    /**
     * <code>optional .exec.DrillbitEndpoint foreman = 7;</code>
     */
    boolean hasForeman();
    /**
     * <code>optional .exec.DrillbitEndpoint foreman = 7;</code>
     */
    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>
     */
    boolean hasState();
    /**
     * <code>optional .exec.shared.QueryResult.QueryState state = 8;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState getState();

    /**
     * <code>optional int32 total_fragments = 9;</code>
     */
    boolean hasTotalFragments();
    /**
     * <code>optional int32 total_fragments = 9;</code>
     */
    int getTotalFragments();

    /**
     * <code>optional int32 finished_fragments = 10;</code>
     */
    boolean hasFinishedFragments();
    /**
     * <code>optional int32 finished_fragments = 10;</code>
     */
    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>
     */
    boolean hasUser();
    /**
     * <code>optional string user = 12 [default = "-"];</code>
     */
    java.lang.String getUser();
    /**
     * <code>optional string user = 12 [default = "-"];</code>
     */
    com.google.protobuf.ByteString
        getUserBytes();

    /**
     * <code>optional string error = 13;</code>
     */
    boolean hasError();
    /**
     * <code>optional string error = 13;</code>
     */
    java.lang.String getError();
    /**
     * <code>optional string error = 13;</code>
     */
    com.google.protobuf.ByteString
        getErrorBytes();

    /**
     * <code>optional string verboseError = 14;</code>
     */
    boolean hasVerboseError();
    /**
     * <code>optional string verboseError = 14;</code>
     */
    java.lang.String getVerboseError();
    /**
     * <code>optional string verboseError = 14;</code>
     */
    com.google.protobuf.ByteString
        getVerboseErrorBytes();

    /**
     * <code>optional string error_id = 15;</code>
     */
    boolean hasErrorId();
    /**
     * <code>optional string error_id = 15;</code>
     */
    java.lang.String getErrorId();
    /**
     * <code>optional string error_id = 15;</code>
     */
    com.google.protobuf.ByteString
        getErrorIdBytes();

    /**
     * <code>optional string error_node = 16;</code>
     */
    boolean hasErrorNode();
    /**
     * <code>optional string error_node = 16;</code>
     */
    java.lang.String getErrorNode();
    /**
     * <code>optional string error_node = 16;</code>
     */
    com.google.protobuf.ByteString
        getErrorNodeBytes();

    /**
     * <code>optional string options_json = 17;</code>
     */
    boolean hasOptionsJson();
    /**
     * <code>optional string options_json = 17;</code>
     */
    java.lang.String getOptionsJson();
    /**
     * <code>optional string options_json = 17;</code>
     */
    com.google.protobuf.ByteString
        getOptionsJsonBytes();

    /**
     * <code>optional int64 planEnd = 18;</code>
     */
    boolean hasPlanEnd();
    /**
     * <code>optional int64 planEnd = 18;</code>
     */
    long getPlanEnd();

    /**
     * <code>optional int64 queueWaitEnd = 19;</code>
     */
    boolean hasQueueWaitEnd();
    /**
     * <code>optional int64 queueWaitEnd = 19;</code>
     */
    long getQueueWaitEnd();

    /**
     * <code>optional double total_cost = 20;</code>
     */
    boolean hasTotalCost();
    /**
     * <code>optional double total_cost = 20;</code>
     */
    double getTotalCost();

    /**
     * <code>optional string queue_name = 21 [default = "-"];</code>
     */
    boolean hasQueueName();
    /**
     * <code>optional string queue_name = 21 [default = "-"];</code>
     */
    java.lang.String getQueueName();
    /**
     * <code>optional string queue_name = 21 [default = "-"];</code>
     */
    com.google.protobuf.ByteString
        getQueueNameBytes();

    /**
     * <code>optional string queryId = 22;</code>
     */
    boolean hasQueryId();
    /**
     * <code>optional string queryId = 22;</code>
     */
    java.lang.String getQueryId();
    /**
     * <code>optional string queryId = 22;</code>
     */
    com.google.protobuf.ByteString
        getQueryIdBytes();

    /**
     * <code>optional int32 autoLimit = 23;</code>
     */
    boolean hasAutoLimit();
    /**
     * <code>optional int32 autoLimit = 23;</code>
     */
    int getAutoLimit();
  }
  /**
   * 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;
      start_ = 0L;
      end_ = 0L;
      query_ = "";
      plan_ = "";
      state_ = 0;
      totalFragments_ = 0;
      finishedFragments_ = 0;
      fragmentProfile_ = java.util.Collections.emptyList();
      user_ = "-";
      error_ = "";
      verboseError_ = "";
      errorId_ = "";
      errorNode_ = "";
      optionsJson_ = "";
      planEnd_ = 0L;
      queueWaitEnd_ = 0L;
      totalCost_ = 0D;
      queueName_ = "-";
      queryId_ = "";
      autoLimit_ = 0;
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private QueryProfile(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 10: {
              org.apache.drill.exec.proto.UserBitShared.QueryId.Builder subBuilder = null;
              if (((bitField0_ & 0x00000001) == 0x00000001)) {
                subBuilder = id_.toBuilder();
              }
              id_ = input.readMessage(org.apache.drill.exec.proto.UserBitShared.QueryId.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(id_);
                id_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000001;
              break;
            }
            case 16: {
              int rawValue = input.readEnum();
                @SuppressWarnings("deprecation")
              org.apache.drill.exec.proto.UserBitShared.QueryType value = org.apache.drill.exec.proto.UserBitShared.QueryType.valueOf(rawValue);
              if (value == null) {
                unknownFields.mergeVarintField(2, rawValue);
              } else {
                bitField0_ |= 0x00000002;
                type_ = rawValue;
              }
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              start_ = input.readInt64();
              break;
            }
            case 32: {
              bitField0_ |= 0x00000008;
              end_ = input.readInt64();
              break;
            }
            case 42: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00000010;
              query_ = bs;
              break;
            }
            case 50: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00000020;
              plan_ = bs;
              break;
            }
            case 58: {
              org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder subBuilder = null;
              if (((bitField0_ & 0x00000040) == 0x00000040)) {
                subBuilder = foreman_.toBuilder();
              }
              foreman_ = input.readMessage(org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(foreman_);
                foreman_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000040;
              break;
            }
            case 64: {
              int rawValue = input.readEnum();
                @SuppressWarnings("deprecation")
              org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState value = org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.valueOf(rawValue);
              if (value == null) {
                unknownFields.mergeVarintField(8, rawValue);
              } else {
                bitField0_ |= 0x00000080;
                state_ = rawValue;
              }
              break;
            }
            case 72: {
              bitField0_ |= 0x00000100;
              totalFragments_ = input.readInt32();
              break;
            }
            case 80: {
              bitField0_ |= 0x00000200;
              finishedFragments_ = input.readInt32();
              break;
            }
            case 90: {
              if (!((mutable_bitField0_ & 0x00000400) == 0x00000400)) {
                fragmentProfile_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile>();
                mutable_bitField0_ |= 0x00000400;
              }
              fragmentProfile_.add(
                  input.readMessage(org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile.PARSER, extensionRegistry));
              break;
            }
            case 98: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00000400;
              user_ = bs;
              break;
            }
            case 106: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00000800;
              error_ = bs;
              break;
            }
            case 114: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00001000;
              verboseError_ = bs;
              break;
            }
            case 122: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00002000;
              errorId_ = bs;
              break;
            }
            case 130: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00004000;
              errorNode_ = bs;
              break;
            }
            case 138: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00008000;
              optionsJson_ = bs;
              break;
            }
            case 144: {
              bitField0_ |= 0x00010000;
              planEnd_ = input.readInt64();
              break;
            }
            case 152: {
              bitField0_ |= 0x00020000;
              queueWaitEnd_ = input.readInt64();
              break;
            }
            case 161: {
              bitField0_ |= 0x00040000;
              totalCost_ = input.readDouble();
              break;
            }
            case 170: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00080000;
              queueName_ = bs;
              break;
            }
            case 178: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00100000;
              queryId_ = bs;
              break;
            }
            case 184: {
              bitField0_ |= 0x00200000;
              autoLimit_ = input.readInt32();
              break;
            }
            default: {
              if (!parseUnknownField(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000400) == 0x00000400)) {
          fragmentProfile_ = java.util.Collections.unmodifiableList(fragmentProfile_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    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>
     */
    public boolean hasId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional .exec.shared.QueryId id = 1;</code>
     */
    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>
     */
    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>
     */
    public boolean hasType() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional .exec.shared.QueryType type = 2;</code>
     */
    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>
     */
    public boolean hasStart() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional int64 start = 3;</code>
     */
    public long getStart() {
      return start_;
    }

    public static final int END_FIELD_NUMBER = 4;
    private long end_;
    /**
     * <code>optional int64 end = 4;</code>
     */
    public boolean hasEnd() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>optional int64 end = 4;</code>
     */
    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>
     */
    public boolean hasQuery() {
      return ((bitField0_ & 0x00000010) == 0x00000010);
    }
    /**
     * <code>optional string query = 5;</code>
     */
    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>
     */
    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>
     */
    public boolean hasPlan() {
      return ((bitField0_ & 0x00000020) == 0x00000020);
    }
    /**
     * <code>optional string plan = 6;</code>
     */
    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>
     */
    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>
     */
    public boolean hasForeman() {
      return ((bitField0_ & 0x00000040) == 0x00000040);
    }
    /**
     * <code>optional .exec.DrillbitEndpoint foreman = 7;</code>
     */
    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>
     */
    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>
     */
    public boolean hasState() {
      return ((bitField0_ & 0x00000080) == 0x00000080);
    }
    /**
     * <code>optional .exec.shared.QueryResult.QueryState state = 8;</code>
     */
    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>
     */
    public boolean hasTotalFragments() {
      return ((bitField0_ & 0x00000100) == 0x00000100);
    }
    /**
     * <code>optional int32 total_fragments = 9;</code>
     */
    public int getTotalFragments() {
      return totalFragments_;
    }

    public static final int FINISHED_FRAGMENTS_FIELD_NUMBER = 10;
    private int finishedFragments_;
    /**
     * <code>optional int32 finished_fragments = 10;</code>
     */
    public boolean hasFinishedFragments() {
      return ((bitField0_ & 0x00000200) == 0x00000200);
    }
    /**
     * <code>optional int32 finished_fragments = 10;</code>
     */
    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>
     */
    public java.util.List<org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile> getFragmentProfileList() {
      return fragmentProfile_;
    }
    /**
     * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
     */
    public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfileOrBuilder> 
        getFragmentProfileOrBuilderList() {
      return fragmentProfile_;
    }
    /**
     * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
     */
    public int getFragmentProfileCount() {
      return fragmentProfile_.size();
    }
    /**
     * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
     */
    public org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile getFragmentProfile(int index) {
      return fragmentProfile_.get(index);
    }
    /**
     * <code>repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;</code>
     */
    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>
     */
    public boolean hasUser() {
      return ((bitField0_ & 0x00000400) == 0x00000400);
    }
    /**
     * <code>optional string user = 12 [default = "-"];</code>
     */
    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>
     */
    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>
     */
    public boolean hasError() {
      return ((bitField0_ & 0x00000800) == 0x00000800);
    }
    /**
     * <code>optional string error = 13;</code>
     */
    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>
     */
    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>
     */
    public boolean hasVerboseError() {
      return ((bitField0_ & 0x00001000) == 0x00001000);
    }
    /**
     * <code>optional string verboseError = 14;</code>
     */
    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>
     */
    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>
     */
    public boolean hasErrorId() {
      return ((bitField0_ & 0x00002000) == 0x00002000);
    }
    /**
     * <code>optional string error_id = 15;</code>
     */
    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>
     */
    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>
     */
    public boolean hasErrorNode() {
      return ((bitField0_ & 0x00004000) == 0x00004000);
    }
    /**
     * <code>optional string error_node = 16;</code>
     */
    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>
     */
    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>
     */
    public boolean hasOptionsJson() {
      return ((bitField0_ & 0x00008000) == 0x00008000);
    }
    /**
     * <code>optional string options_json = 17;</code>
     */
    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>
     */
    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>
     */
    public boolean hasPlanEnd() {
      return ((bitField0_ & 0x00010000) == 0x00010000);
    }
    /**
     * <code>optional int64 planEnd = 18;</code>
     */
    public long getPlanEnd() {
      return planEnd_;
    }

    public static final int QUEUEWAITEND_FIELD_NUMBER = 19;
    private long queueWaitEnd_;
    /**
     * <code>optional int64 queueWaitEnd = 19;</code>
     */
    public boolean hasQueueWaitEnd() {
      return ((bitField0_ & 0x00020000) == 0x00020000);
    }
    /**
     * <code>optional int64 queueWaitEnd = 19;</code>
     */
    public long getQueueWaitEnd() {
      return queueWaitEnd_;
    }

    public static final int TOTAL_COST_FIELD_NUMBER = 20;
    private double totalCost_;
    /**
     * <code>optional double total_cost = 20;</code>
     */
    public boolean hasTotalCost() {
      return ((bitField0_ & 0x00040000) == 0x00040000);
    }
    /**
     * <code>optional double total_cost = 20;</code>
     */
    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>
     */
    public boolean hasQueueName() {
      return ((bitField0_ & 0x00080000) == 0x00080000);
    }
    /**
     * <code>optional string queue_name = 21 [default = "-"];</code>
     */
    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>
     */
    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>
     */
    public boolean hasQueryId() {
      return ((bitField0_ & 0x00100000) == 0x00100000);
    }
    /**
     * <code>optional string queryId = 22;</code>
     */
    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>
     */
    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>
     */
    public boolean hasAutoLimit() {
      return ((bitField0_ & 0x00200000) == 0x00200000);
    }
    /**
     * <code>optional int32 autoLimit = 23;</code>
     */
    public int getAutoLimit() {
      return autoLimit_;
    }

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

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

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, getId());
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(2, type_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(3, start_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(4, end_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, query_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, plan_);
      }
      if (((bitField0_ & 0x00000040) == 0x00000040)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(7, getForeman());
      }
      if (((bitField0_ & 0x00000080) == 0x00000080)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(8, state_);
      }
      if (((bitField0_ & 0x00000100) == 0x00000100)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(9, totalFragments_);
      }
      if (((bitField0_ & 0x00000200) == 0x00000200)) {
        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) == 0x00000400)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(12, user_);
      }
      if (((bitField0_ & 0x00000800) == 0x00000800)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(13, error_);
      }
      if (((bitField0_ & 0x00001000) == 0x00001000)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(14, verboseError_);
      }
      if (((bitField0_ & 0x00002000) == 0x00002000)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(15, errorId_);
      }
      if (((bitField0_ & 0x00004000) == 0x00004000)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(16, errorNode_);
      }
      if (((bitField0_ & 0x00008000) == 0x00008000)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(17, optionsJson_);
      }
      if (((bitField0_ & 0x00010000) == 0x00010000)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(18, planEnd_);
      }
      if (((bitField0_ & 0x00020000) == 0x00020000)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(19, queueWaitEnd_);
      }
      if (((bitField0_ & 0x00040000) == 0x00040000)) {
        size += com.google.protobuf.CodedOutputStream
          .computeDoubleSize(20, totalCost_);
      }
      if (((bitField0_ & 0x00080000) == 0x00080000)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(21, queueName_);
      }
      if (((bitField0_ & 0x00100000) == 0x00100000)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(22, queryId_);
      }
      if (((bitField0_ & 0x00200000) == 0x00200000)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(23, autoLimit_);
      }
      size += unknownFields.getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.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;

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

    @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();
      }
      hash = (29 * hash) + unknownFields.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();
          bitField0_ = (bitField0_ & ~0x00000400);
        } else {
          fragmentProfileBuilder_.clear();
        }
        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);
        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) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        if (idBuilder_ == null) {
          result.id_ = id_;
        } else {
          result.id_ = idBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.type_ = type_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.start_ = start_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.end_ = end_;
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000010;
        }
        result.query_ = query_;
        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
          to_bitField0_ |= 0x00000020;
        }
        result.plan_ = plan_;
        if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
          to_bitField0_ |= 0x00000040;
        }
        if (foremanBuilder_ == null) {
          result.foreman_ = foreman_;
        } else {
          result.foreman_ = foremanBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000080) == 0x00000080)) {
          to_bitField0_ |= 0x00000080;
        }
        result.state_ = state_;
        if (((from_bitField0_ & 0x00000100) == 0x00000100)) {
          to_bitField0_ |= 0x00000100;
        }
        result.totalFragments_ = totalFragments_;
        if (((from_bitField0_ & 0x00000200) == 0x00000200)) {
          to_bitField0_ |= 0x00000200;
        }
        result.finishedFragments_ = finishedFragments_;
        if (fragmentProfileBuilder_ == null) {
          if (((bitField0_ & 0x00000400) == 0x00000400)) {
            fragmentProfile_ = java.util.Collections.unmodifiableList(fragmentProfile_);
            bitField0_ = (bitField0_ & ~0x00000400);
          }
          result.fragmentProfile_ = fragmentProfile_;
        } else {
          result.fragmentProfile_ = fragmentProfileBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000800) == 0x00000800)) {
          to_bitField0_ |= 0x00000400;
        }
        result.user_ = user_;
        if (((from_bitField0_ & 0x00001000) == 0x00001000)) {
          to_bitField0_ |= 0x00000800;
        }
        result.error_ = error_;
        if (((from_bitField0_ & 0x00002000) == 0x00002000)) {
          to_bitField0_ |= 0x00001000;
        }
        result.verboseError_ = verboseError_;
        if (((from_bitField0_ & 0x00004000) == 0x00004000)) {
          to_bitField0_ |= 0x00002000;
        }
        result.errorId_ = errorId_;
        if (((from_bitField0_ & 0x00008000) == 0x00008000)) {
          to_bitField0_ |= 0x00004000;
        }
        result.errorNode_ = errorNode_;
        if (((from_bitField0_ & 0x00010000) == 0x00010000)) {
          to_bitField0_ |= 0x00008000;
        }
        result.optionsJson_ = optionsJson_;
        if (((from_bitField0_ & 0x00020000) == 0x00020000)) {
          to_bitField0_ |= 0x00010000;
        }
        result.planEnd_ = planEnd_;
        if (((from_bitField0_ & 0x00040000) == 0x00040000)) {
          to_bitField0_ |= 0x00020000;
        }
        result.queueWaitEnd_ = queueWaitEnd_;
        if (((from_bitField0_ & 0x00080000) == 0x00080000)) {
          to_bitField0_ |= 0x00040000;
        }
        result.totalCost_ = totalCost_;
        if (((from_bitField0_ & 0x00100000) == 0x00100000)) {
          to_bitField0_ |= 0x00080000;
        }
        result.queueName_ = queueName_;
        if (((from_bitField0_ & 0x00200000) == 0x00200000)) {
          to_bitField0_ |= 0x00100000;
        }
        result.queryId_ = queryId_;
        if (((from_bitField0_ & 0x00400000) == 0x00400000)) {
          to_bitField0_ |= 0x00200000;
        }
        result.autoLimit_ = autoLimit_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return (Builder) super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return (Builder) super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return (Builder) super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return (Builder) super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) 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());
        }
        this.mergeUnknownFields(other.unknownFields);
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.drill.exec.proto.UserBitShared.QueryProfile parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.drill.exec.proto.UserBitShared.QueryProfile) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private org.apache.drill.exec.proto.UserBitShared.QueryId id_ = null;
      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>
       */
      public boolean hasId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional .exec.shared.QueryId id = 1;</code>
       */
      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) == 0x00000001) &&
              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>
       */
      public boolean hasType() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional .exec.shared.QueryType type = 2;</code>
       */
      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>
       */
      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>
       */
      public Builder clearType() {
        bitField0_ = (bitField0_ & ~0x00000002);
        type_ = 1;
        onChanged();
        return this;
      }

      private long start_ ;
      /**
       * <code>optional int64 start = 3;</code>
       */
      public boolean hasStart() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional int64 start = 3;</code>
       */
      public long getStart() {
        return start_;
      }
      /**
       * <code>optional int64 start = 3;</code>
       */
      public Builder setStart(long value) {
        bitField0_ |= 0x00000004;
        start_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 start = 3;</code>
       */
      public Builder clearStart() {
        bitField0_ = (bitField0_ & ~0x00000004);
        start_ = 0L;
        onChanged();
        return this;
      }

      private long end_ ;
      /**
       * <code>optional int64 end = 4;</code>
       */
      public boolean hasEnd() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>optional int64 end = 4;</code>
       */
      public long getEnd() {
        return end_;
      }
      /**
       * <code>optional int64 end = 4;</code>
       */
      public Builder setEnd(long value) {
        bitField0_ |= 0x00000008;
        end_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 end = 4;</code>
       */
      public Builder clearEnd() {
        bitField0_ = (bitField0_ & ~0x00000008);
        end_ = 0L;
        onChanged();
        return this;
      }

      private java.lang.Object query_ = "";
      /**
       * <code>optional string query = 5;</code>
       */
      public boolean hasQuery() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      /**
       * <code>optional string query = 5;</code>
       */
      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>
       */
      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>
       */
      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>
       */
      public Builder clearQuery() {
        bitField0_ = (bitField0_ & ~0x00000010);
        query_ = getDefaultInstance().getQuery();
        onChanged();
        return this;
      }
      /**
       * <code>optional string query = 5;</code>
       */
      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>
       */
      public boolean hasPlan() {
        return ((bitField0_ & 0x00000020) == 0x00000020);
      }
      /**
       * <code>optional string plan = 6;</code>
       */
      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>
       */
      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>
       */
      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>
       */
      public Builder clearPlan() {
        bitField0_ = (bitField0_ & ~0x00000020);
        plan_ = getDefaultInstance().getPlan();
        onChanged();
        return this;
      }
      /**
       * <code>optional string plan = 6;</code>
       */
      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_ = null;
      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>
       */
      public boolean hasForeman() {
        return ((bitField0_ & 0x00000040) == 0x00000040);
      }
      /**
       * <code>optional .exec.DrillbitEndpoint foreman = 7;</code>
       */
      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) == 0x00000040) &&
              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>
       */
      public boolean hasState() {
        return ((bitField0_ & 0x00000080) == 0x00000080);
      }
      /**
       * <code>optional .exec.shared.QueryResult.QueryState state = 8;</code>
       */
      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>
       */
      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>
       */
      public Builder clearState() {
        bitField0_ = (bitField0_ & ~0x00000080);
        state_ = 0;
        onChanged();
        return this;
      }

      private int totalFragments_ ;
      /**
       * <code>optional int32 total_fragments = 9;</code>
       */
      public boolean hasTotalFragments() {
        return ((bitField0_ & 0x00000100) == 0x00000100);
      }
      /**
       * <code>optional int32 total_fragments = 9;</code>
       */
      public int getTotalFragments() {
        return totalFragments_;
      }
      /**
       * <code>optional int32 total_fragments = 9;</code>
       */
      public Builder setTotalFragments(int value) {
        bitField0_ |= 0x00000100;
        totalFragments_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 total_fragments = 9;</code>
       */
      public Builder clearTotalFragments() {
        bitField0_ = (bitField0_ & ~0x00000100);
        totalFragments_ = 0;
        onChanged();
        return this;
      }

      private int finishedFragments_ ;
      /**
       * <code>optional int32 finished_fragments = 10;</code>
       */
      public boolean hasFinishedFragments() {
        return ((bitField0_ & 0x00000200) == 0x00000200);
      }
      /**
       * <code>optional int32 finished_fragments = 10;</code>
       */
      public int getFinishedFragments() {
        return finishedFragments_;
      }
      /**
       * <code>optional int32 finished_fragments = 10;</code>
       */
      public Builder setFinishedFragments(int value) {
        bitField0_ |= 0x00000200;
        finishedFragments_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 finished_fragments = 10;</code>
       */
      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) == 0x00000400)) {
          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) == 0x00000400),
                  getParentForChildren(),
                  isClean());
          fragmentProfile_ = null;
        }
        return fragmentProfileBuilder_;
      }

      private java.lang.Object user_ = "-";
      /**
       * <code>optional string user = 12 [default = "-"];</code>
       */
      public boolean hasUser() {
        return ((bitField0_ & 0x00000800) == 0x00000800);
      }
      /**
       * <code>optional string user = 12 [default = "-"];</code>
       */
      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>
       */
      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>
       */
      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>
       */
      public Builder clearUser() {
        bitField0_ = (bitField0_ & ~0x00000800);
        user_ = getDefaultInstance().getUser();
        onChanged();
        return this;
      }
      /**
       * <code>optional string user = 12 [default = "-"];</code>
       */
      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>
       */
      public boolean hasError() {
        return ((bitField0_ & 0x00001000) == 0x00001000);
      }
      /**
       * <code>optional string error = 13;</code>
       */
      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>
       */
      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>
       */
      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>
       */
      public Builder clearError() {
        bitField0_ = (bitField0_ & ~0x00001000);
        error_ = getDefaultInstance().getError();
        onChanged();
        return this;
      }
      /**
       * <code>optional string error = 13;</code>
       */
      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>
       */
      public boolean hasVerboseError() {
        return ((bitField0_ & 0x00002000) == 0x00002000);
      }
      /**
       * <code>optional string verboseError = 14;</code>
       */
      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>
       */
      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>
       */
      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>
       */
      public Builder clearVerboseError() {
        bitField0_ = (bitField0_ & ~0x00002000);
        verboseError_ = getDefaultInstance().getVerboseError();
        onChanged();
        return this;
      }
      /**
       * <code>optional string verboseError = 14;</code>
       */
      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>
       */
      public boolean hasErrorId() {
        return ((bitField0_ & 0x00004000) == 0x00004000);
      }
      /**
       * <code>optional string error_id = 15;</code>
       */
      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>
       */
      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>
       */
      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>
       */
      public Builder clearErrorId() {
        bitField0_ = (bitField0_ & ~0x00004000);
        errorId_ = getDefaultInstance().getErrorId();
        onChanged();
        return this;
      }
      /**
       * <code>optional string error_id = 15;</code>
       */
      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>
       */
      public boolean hasErrorNode() {
        return ((bitField0_ & 0x00008000) == 0x00008000);
      }
      /**
       * <code>optional string error_node = 16;</code>
       */
      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>
       */
      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>
       */
      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>
       */
      public Builder clearErrorNode() {
        bitField0_ = (bitField0_ & ~0x00008000);
        errorNode_ = getDefaultInstance().getErrorNode();
        onChanged();
        return this;
      }
      /**
       * <code>optional string error_node = 16;</code>
       */
      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>
       */
      public boolean hasOptionsJson() {
        return ((bitField0_ & 0x00010000) == 0x00010000);
      }
      /**
       * <code>optional string options_json = 17;</code>
       */
      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>
       */
      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>
       */
      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>
       */
      public Builder clearOptionsJson() {
        bitField0_ = (bitField0_ & ~0x00010000);
        optionsJson_ = getDefaultInstance().getOptionsJson();
        onChanged();
        return this;
      }
      /**
       * <code>optional string options_json = 17;</code>
       */
      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>
       */
      public boolean hasPlanEnd() {
        return ((bitField0_ & 0x00020000) == 0x00020000);
      }
      /**
       * <code>optional int64 planEnd = 18;</code>
       */
      public long getPlanEnd() {
        return planEnd_;
      }
      /**
       * <code>optional int64 planEnd = 18;</code>
       */
      public Builder setPlanEnd(long value) {
        bitField0_ |= 0x00020000;
        planEnd_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 planEnd = 18;</code>
       */
      public Builder clearPlanEnd() {
        bitField0_ = (bitField0_ & ~0x00020000);
        planEnd_ = 0L;
        onChanged();
        return this;
      }

      private long queueWaitEnd_ ;
      /**
       * <code>optional int64 queueWaitEnd = 19;</code>
       */
      public boolean hasQueueWaitEnd() {
        return ((bitField0_ & 0x00040000) == 0x00040000);
      }
      /**
       * <code>optional int64 queueWaitEnd = 19;</code>
       */
      public long getQueueWaitEnd() {
        return queueWaitEnd_;
      }
      /**
       * <code>optional int64 queueWaitEnd = 19;</code>
       */
      public Builder setQueueWaitEnd(long value) {
        bitField0_ |= 0x00040000;
        queueWaitEnd_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 queueWaitEnd = 19;</code>
       */
      public Builder clearQueueWaitEnd() {
        bitField0_ = (bitField0_ & ~0x00040000);
        queueWaitEnd_ = 0L;
        onChanged();
        return this;
      }

      private double totalCost_ ;
      /**
       * <code>optional double total_cost = 20;</code>
       */
      public boolean hasTotalCost() {
        return ((bitField0_ & 0x00080000) == 0x00080000);
      }
      /**
       * <code>optional double total_cost = 20;</code>
       */
      public double getTotalCost() {
        return totalCost_;
      }
      /**
       * <code>optional double total_cost = 20;</code>
       */
      public Builder setTotalCost(double value) {
        bitField0_ |= 0x00080000;
        totalCost_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional double total_cost = 20;</code>
       */
      public Builder clearTotalCost() {
        bitField0_ = (bitField0_ & ~0x00080000);
        totalCost_ = 0D;
        onChanged();
        return this;
      }

      private java.lang.Object queueName_ = "-";
      /**
       * <code>optional string queue_name = 21 [default = "-"];</code>
       */
      public boolean hasQueueName() {
        return ((bitField0_ & 0x00100000) == 0x00100000);
      }
      /**
       * <code>optional string queue_name = 21 [default = "-"];</code>
       */
      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>
       */
      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>
       */
      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>
       */
      public Builder clearQueueName() {
        bitField0_ = (bitField0_ & ~0x00100000);
        queueName_ = getDefaultInstance().getQueueName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string queue_name = 21 [default = "-"];</code>
       */
      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>
       */
      public boolean hasQueryId() {
        return ((bitField0_ & 0x00200000) == 0x00200000);
      }
      /**
       * <code>optional string queryId = 22;</code>
       */
      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>
       */
      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>
       */
      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>
       */
      public Builder clearQueryId() {
        bitField0_ = (bitField0_ & ~0x00200000);
        queryId_ = getDefaultInstance().getQueryId();
        onChanged();
        return this;
      }
      /**
       * <code>optional string queryId = 22;</code>
       */
      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>
       */
      public boolean hasAutoLimit() {
        return ((bitField0_ & 0x00400000) == 0x00400000);
      }
      /**
       * <code>optional int32 autoLimit = 23;</code>
       */
      public int getAutoLimit() {
        return autoLimit_;
      }
      /**
       * <code>optional int32 autoLimit = 23;</code>
       */
      public Builder setAutoLimit(int value) {
        bitField0_ |= 0x00400000;
        autoLimit_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 autoLimit = 23;</code>
       */
      public Builder clearAutoLimit() {
        bitField0_ = (bitField0_ & ~0x00400000);
        autoLimit_ = 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.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 {
        return new QueryProfile(input, extensionRegistry);
      }
    };

    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>
     */
    boolean hasMajorFragmentId();
    /**
     * <code>optional int32 major_fragment_id = 1;</code>
     */
    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() {
      majorFragmentId_ = 0;
      minorFragmentProfile_ = java.util.Collections.emptyList();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private MajorFragmentProfile(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 8: {
              bitField0_ |= 0x00000001;
              majorFragmentId_ = input.readInt32();
              break;
            }
            case 18: {
              if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
                minorFragmentProfile_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile>();
                mutable_bitField0_ |= 0x00000002;
              }
              minorFragmentProfile_.add(
                  input.readMessage(org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.PARSER, extensionRegistry));
              break;
            }
            default: {
              if (!parseUnknownField(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
          minorFragmentProfile_ = java.util.Collections.unmodifiableList(minorFragmentProfile_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    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>
     */
    public boolean hasMajorFragmentId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional int32 major_fragment_id = 1;</code>
     */
    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>
     */
    public java.util.List<org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile> getMinorFragmentProfileList() {
      return minorFragmentProfile_;
    }
    /**
     * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
     */
    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>
     */
    public int getMinorFragmentProfileCount() {
      return minorFragmentProfile_.size();
    }
    /**
     * <code>repeated .exec.shared.MinorFragmentProfile minor_fragment_profile = 2;</code>
     */
    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>
     */
    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) == 0x00000001)) {
        output.writeInt32(1, majorFragmentId_);
      }
      for (int i = 0; i < minorFragmentProfile_.size(); i++) {
        output.writeMessage(2, minorFragmentProfile_.get(i));
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        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 += unknownFields.getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.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;

      boolean result = true;
      result = result && (hasMajorFragmentId() == other.hasMajorFragmentId());
      if (hasMajorFragmentId()) {
        result = result && (getMajorFragmentId()
            == other.getMajorFragmentId());
      }
      result = result && getMinorFragmentProfileList()
          .equals(other.getMinorFragmentProfileList());
      result = result && unknownFields.equals(other.unknownFields);
      return result;
    }

    @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) + unknownFields.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() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getMinorFragmentProfileFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        majorFragmentId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        if (minorFragmentProfileBuilder_ == null) {
          minorFragmentProfile_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000002);
        } else {
          minorFragmentProfileBuilder_.clear();
        }
        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) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.majorFragmentId_ = majorFragmentId_;
        if (minorFragmentProfileBuilder_ == null) {
          if (((bitField0_ & 0x00000002) == 0x00000002)) {
            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 (Builder) super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return (Builder) super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return (Builder) super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return (Builder) super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) 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.unknownFields);
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private int majorFragmentId_ ;
      /**
       * <code>optional int32 major_fragment_id = 1;</code>
       */
      public boolean hasMajorFragmentId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional int32 major_fragment_id = 1;</code>
       */
      public int getMajorFragmentId() {
        return majorFragmentId_;
      }
      /**
       * <code>optional int32 major_fragment_id = 1;</code>
       */
      public Builder setMajorFragmentId(int value) {
        bitField0_ |= 0x00000001;
        majorFragmentId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 major_fragment_id = 1;</code>
       */
      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) == 0x00000002)) {
          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) == 0x00000002),
                  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 {
        return new MajorFragmentProfile(input, extensionRegistry);
      }
    };

    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>
     */
    boolean hasState();
    /**
     * <code>optional .exec.shared.FragmentState state = 1;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.FragmentState getState();

    /**
     * <code>optional .exec.shared.DrillPBError error = 2;</code>
     */
    boolean hasError();
    /**
     * <code>optional .exec.shared.DrillPBError error = 2;</code>
     */
    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>
     */
    boolean hasMinorFragmentId();
    /**
     * <code>optional int32 minor_fragment_id = 3;</code>
     */
    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>
     */
    boolean hasStartTime();
    /**
     * <code>optional int64 start_time = 5;</code>
     */
    long getStartTime();

    /**
     * <code>optional int64 end_time = 6;</code>
     */
    boolean hasEndTime();
    /**
     * <code>optional int64 end_time = 6;</code>
     */
    long getEndTime();

    /**
     * <code>optional int64 memory_used = 7;</code>
     */
    boolean hasMemoryUsed();
    /**
     * <code>optional int64 memory_used = 7;</code>
     */
    long getMemoryUsed();

    /**
     * <code>optional int64 max_memory_used = 8;</code>
     */
    boolean hasMaxMemoryUsed();
    /**
     * <code>optional int64 max_memory_used = 8;</code>
     */
    long getMaxMemoryUsed();

    /**
     * <code>optional .exec.DrillbitEndpoint endpoint = 9;</code>
     */
    boolean hasEndpoint();
    /**
     * <code>optional .exec.DrillbitEndpoint endpoint = 9;</code>
     */
    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>
     */
    boolean hasLastUpdate();
    /**
     * <code>optional int64 last_update = 10;</code>
     */
    long getLastUpdate();

    /**
     * <code>optional int64 last_progress = 11;</code>
     */
    boolean hasLastProgress();
    /**
     * <code>optional int64 last_progress = 11;</code>
     */
    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;
      minorFragmentId_ = 0;
      operatorProfile_ = java.util.Collections.emptyList();
      startTime_ = 0L;
      endTime_ = 0L;
      memoryUsed_ = 0L;
      maxMemoryUsed_ = 0L;
      lastUpdate_ = 0L;
      lastProgress_ = 0L;
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private MinorFragmentProfile(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 8: {
              int rawValue = input.readEnum();
                @SuppressWarnings("deprecation")
              org.apache.drill.exec.proto.UserBitShared.FragmentState value = org.apache.drill.exec.proto.UserBitShared.FragmentState.valueOf(rawValue);
              if (value == null) {
                unknownFields.mergeVarintField(1, rawValue);
              } else {
                bitField0_ |= 0x00000001;
                state_ = rawValue;
              }
              break;
            }
            case 18: {
              org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder subBuilder = null;
              if (((bitField0_ & 0x00000002) == 0x00000002)) {
                subBuilder = error_.toBuilder();
              }
              error_ = input.readMessage(org.apache.drill.exec.proto.UserBitShared.DrillPBError.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(error_);
                error_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000002;
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              minorFragmentId_ = input.readInt32();
              break;
            }
            case 34: {
              if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
                operatorProfile_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserBitShared.OperatorProfile>();
                mutable_bitField0_ |= 0x00000008;
              }
              operatorProfile_.add(
                  input.readMessage(org.apache.drill.exec.proto.UserBitShared.OperatorProfile.PARSER, extensionRegistry));
              break;
            }
            case 40: {
              bitField0_ |= 0x00000008;
              startTime_ = input.readInt64();
              break;
            }
            case 48: {
              bitField0_ |= 0x00000010;
              endTime_ = input.readInt64();
              break;
            }
            case 56: {
              bitField0_ |= 0x00000020;
              memoryUsed_ = input.readInt64();
              break;
            }
            case 64: {
              bitField0_ |= 0x00000040;
              maxMemoryUsed_ = input.readInt64();
              break;
            }
            case 74: {
              org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder subBuilder = null;
              if (((bitField0_ & 0x00000080) == 0x00000080)) {
                subBuilder = endpoint_.toBuilder();
              }
              endpoint_ = input.readMessage(org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(endpoint_);
                endpoint_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000080;
              break;
            }
            case 80: {
              bitField0_ |= 0x00000100;
              lastUpdate_ = input.readInt64();
              break;
            }
            case 88: {
              bitField0_ |= 0x00000200;
              lastProgress_ = input.readInt64();
              break;
            }
            default: {
              if (!parseUnknownField(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
          operatorProfile_ = java.util.Collections.unmodifiableList(operatorProfile_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    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>
     */
    public boolean hasState() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional .exec.shared.FragmentState state = 1;</code>
     */
    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>
     */
    public boolean hasError() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional .exec.shared.DrillPBError error = 2;</code>
     */
    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>
     */
    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>
     */
    public boolean hasMinorFragmentId() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional int32 minor_fragment_id = 3;</code>
     */
    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>
     */
    public java.util.List<org.apache.drill.exec.proto.UserBitShared.OperatorProfile> getOperatorProfileList() {
      return operatorProfile_;
    }
    /**
     * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
     */
    public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.OperatorProfileOrBuilder> 
        getOperatorProfileOrBuilderList() {
      return operatorProfile_;
    }
    /**
     * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
     */
    public int getOperatorProfileCount() {
      return operatorProfile_.size();
    }
    /**
     * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
     */
    public org.apache.drill.exec.proto.UserBitShared.OperatorProfile getOperatorProfile(int index) {
      return operatorProfile_.get(index);
    }
    /**
     * <code>repeated .exec.shared.OperatorProfile operator_profile = 4;</code>
     */
    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>
     */
    public boolean hasStartTime() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>optional int64 start_time = 5;</code>
     */
    public long getStartTime() {
      return startTime_;
    }

    public static final int END_TIME_FIELD_NUMBER = 6;
    private long endTime_;
    /**
     * <code>optional int64 end_time = 6;</code>
     */
    public boolean hasEndTime() {
      return ((bitField0_ & 0x00000010) == 0x00000010);
    }
    /**
     * <code>optional int64 end_time = 6;</code>
     */
    public long getEndTime() {
      return endTime_;
    }

    public static final int MEMORY_USED_FIELD_NUMBER = 7;
    private long memoryUsed_;
    /**
     * <code>optional int64 memory_used = 7;</code>
     */
    public boolean hasMemoryUsed() {
      return ((bitField0_ & 0x00000020) == 0x00000020);
    }
    /**
     * <code>optional int64 memory_used = 7;</code>
     */
    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>
     */
    public boolean hasMaxMemoryUsed() {
      return ((bitField0_ & 0x00000040) == 0x00000040);
    }
    /**
     * <code>optional int64 max_memory_used = 8;</code>
     */
    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>
     */
    public boolean hasEndpoint() {
      return ((bitField0_ & 0x00000080) == 0x00000080);
    }
    /**
     * <code>optional .exec.DrillbitEndpoint endpoint = 9;</code>
     */
    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>
     */
    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>
     */
    public boolean hasLastUpdate() {
      return ((bitField0_ & 0x00000100) == 0x00000100);
    }
    /**
     * <code>optional int64 last_update = 10;</code>
     */
    public long getLastUpdate() {
      return lastUpdate_;
    }

    public static final int LAST_PROGRESS_FIELD_NUMBER = 11;
    private long lastProgress_;
    /**
     * <code>optional int64 last_progress = 11;</code>
     */
    public boolean hasLastProgress() {
      return ((bitField0_ & 0x00000200) == 0x00000200);
    }
    /**
     * <code>optional int64 last_progress = 11;</code>
     */
    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) == 0x00000001)) {
        output.writeEnum(1, state_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeMessage(2, getError());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeInt32(3, minorFragmentId_);
      }
      for (int i = 0; i < operatorProfile_.size(); i++) {
        output.writeMessage(4, operatorProfile_.get(i));
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeInt64(5, startTime_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        output.writeInt64(6, endTime_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        output.writeInt64(7, memoryUsed_);
      }
      if (((bitField0_ & 0x00000040) == 0x00000040)) {
        output.writeInt64(8, maxMemoryUsed_);
      }
      if (((bitField0_ & 0x00000080) == 0x00000080)) {
        output.writeMessage(9, getEndpoint());
      }
      if (((bitField0_ & 0x00000100) == 0x00000100)) {
        output.writeInt64(10, lastUpdate_);
      }
      if (((bitField0_ & 0x00000200) == 0x00000200)) {
        output.writeInt64(11, lastProgress_);
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(1, state_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, getError());
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        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) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(5, startTime_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(6, endTime_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(7, memoryUsed_);
      }
      if (((bitField0_ & 0x00000040) == 0x00000040)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(8, maxMemoryUsed_);
      }
      if (((bitField0_ & 0x00000080) == 0x00000080)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(9, getEndpoint());
      }
      if (((bitField0_ & 0x00000100) == 0x00000100)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(10, lastUpdate_);
      }
      if (((bitField0_ & 0x00000200) == 0x00000200)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(11, lastProgress_);
      }
      size += unknownFields.getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.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;

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

    @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) + unknownFields.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();
          bitField0_ = (bitField0_ & ~0x00000008);
        } else {
          operatorProfileBuilder_.clear();
        }
        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) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.state_ = state_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        if (errorBuilder_ == null) {
          result.error_ = error_;
        } else {
          result.error_ = errorBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.minorFragmentId_ = minorFragmentId_;
        if (operatorProfileBuilder_ == null) {
          if (((bitField0_ & 0x00000008) == 0x00000008)) {
            operatorProfile_ = java.util.Collections.unmodifiableList(operatorProfile_);
            bitField0_ = (bitField0_ & ~0x00000008);
          }
          result.operatorProfile_ = operatorProfile_;
        } else {
          result.operatorProfile_ = operatorProfileBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000008;
        }
        result.startTime_ = startTime_;
        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
          to_bitField0_ |= 0x00000010;
        }
        result.endTime_ = endTime_;
        if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
          to_bitField0_ |= 0x00000020;
        }
        result.memoryUsed_ = memoryUsed_;
        if (((from_bitField0_ & 0x00000080) == 0x00000080)) {
          to_bitField0_ |= 0x00000040;
        }
        result.maxMemoryUsed_ = maxMemoryUsed_;
        if (((from_bitField0_ & 0x00000100) == 0x00000100)) {
          to_bitField0_ |= 0x00000080;
        }
        if (endpointBuilder_ == null) {
          result.endpoint_ = endpoint_;
        } else {
          result.endpoint_ = endpointBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000200) == 0x00000200)) {
          to_bitField0_ |= 0x00000100;
        }
        result.lastUpdate_ = lastUpdate_;
        if (((from_bitField0_ & 0x00000400) == 0x00000400)) {
          to_bitField0_ |= 0x00000200;
        }
        result.lastProgress_ = lastProgress_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return (Builder) super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return (Builder) super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return (Builder) super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return (Builder) super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) 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.unknownFields);
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private int state_ = 0;
      /**
       * <code>optional .exec.shared.FragmentState state = 1;</code>
       */
      public boolean hasState() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional .exec.shared.FragmentState state = 1;</code>
       */
      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>
       */
      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>
       */
      public Builder clearState() {
        bitField0_ = (bitField0_ & ~0x00000001);
        state_ = 0;
        onChanged();
        return this;
      }

      private org.apache.drill.exec.proto.UserBitShared.DrillPBError error_ = null;
      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>
       */
      public boolean hasError() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 2;</code>
       */
      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) == 0x00000002) &&
              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>
       */
      public boolean hasMinorFragmentId() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional int32 minor_fragment_id = 3;</code>
       */
      public int getMinorFragmentId() {
        return minorFragmentId_;
      }
      /**
       * <code>optional int32 minor_fragment_id = 3;</code>
       */
      public Builder setMinorFragmentId(int value) {
        bitField0_ |= 0x00000004;
        minorFragmentId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 minor_fragment_id = 3;</code>
       */
      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) == 0x00000008)) {
          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) == 0x00000008),
                  getParentForChildren(),
                  isClean());
          operatorProfile_ = null;
        }
        return operatorProfileBuilder_;
      }

      private long startTime_ ;
      /**
       * <code>optional int64 start_time = 5;</code>
       */
      public boolean hasStartTime() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      /**
       * <code>optional int64 start_time = 5;</code>
       */
      public long getStartTime() {
        return startTime_;
      }
      /**
       * <code>optional int64 start_time = 5;</code>
       */
      public Builder setStartTime(long value) {
        bitField0_ |= 0x00000010;
        startTime_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 start_time = 5;</code>
       */
      public Builder clearStartTime() {
        bitField0_ = (bitField0_ & ~0x00000010);
        startTime_ = 0L;
        onChanged();
        return this;
      }

      private long endTime_ ;
      /**
       * <code>optional int64 end_time = 6;</code>
       */
      public boolean hasEndTime() {
        return ((bitField0_ & 0x00000020) == 0x00000020);
      }
      /**
       * <code>optional int64 end_time = 6;</code>
       */
      public long getEndTime() {
        return endTime_;
      }
      /**
       * <code>optional int64 end_time = 6;</code>
       */
      public Builder setEndTime(long value) {
        bitField0_ |= 0x00000020;
        endTime_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 end_time = 6;</code>
       */
      public Builder clearEndTime() {
        bitField0_ = (bitField0_ & ~0x00000020);
        endTime_ = 0L;
        onChanged();
        return this;
      }

      private long memoryUsed_ ;
      /**
       * <code>optional int64 memory_used = 7;</code>
       */
      public boolean hasMemoryUsed() {
        return ((bitField0_ & 0x00000040) == 0x00000040);
      }
      /**
       * <code>optional int64 memory_used = 7;</code>
       */
      public long getMemoryUsed() {
        return memoryUsed_;
      }
      /**
       * <code>optional int64 memory_used = 7;</code>
       */
      public Builder setMemoryUsed(long value) {
        bitField0_ |= 0x00000040;
        memoryUsed_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 memory_used = 7;</code>
       */
      public Builder clearMemoryUsed() {
        bitField0_ = (bitField0_ & ~0x00000040);
        memoryUsed_ = 0L;
        onChanged();
        return this;
      }

      private long maxMemoryUsed_ ;
      /**
       * <code>optional int64 max_memory_used = 8;</code>
       */
      public boolean hasMaxMemoryUsed() {
        return ((bitField0_ & 0x00000080) == 0x00000080);
      }
      /**
       * <code>optional int64 max_memory_used = 8;</code>
       */
      public long getMaxMemoryUsed() {
        return maxMemoryUsed_;
      }
      /**
       * <code>optional int64 max_memory_used = 8;</code>
       */
      public Builder setMaxMemoryUsed(long value) {
        bitField0_ |= 0x00000080;
        maxMemoryUsed_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 max_memory_used = 8;</code>
       */
      public Builder clearMaxMemoryUsed() {
        bitField0_ = (bitField0_ & ~0x00000080);
        maxMemoryUsed_ = 0L;
        onChanged();
        return this;
      }

      private org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint endpoint_ = null;
      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>
       */
      public boolean hasEndpoint() {
        return ((bitField0_ & 0x00000100) == 0x00000100);
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 9;</code>
       */
      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) == 0x00000100) &&
              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>
       */
      public boolean hasLastUpdate() {
        return ((bitField0_ & 0x00000200) == 0x00000200);
      }
      /**
       * <code>optional int64 last_update = 10;</code>
       */
      public long getLastUpdate() {
        return lastUpdate_;
      }
      /**
       * <code>optional int64 last_update = 10;</code>
       */
      public Builder setLastUpdate(long value) {
        bitField0_ |= 0x00000200;
        lastUpdate_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 last_update = 10;</code>
       */
      public Builder clearLastUpdate() {
        bitField0_ = (bitField0_ & ~0x00000200);
        lastUpdate_ = 0L;
        onChanged();
        return this;
      }

      private long lastProgress_ ;
      /**
       * <code>optional int64 last_progress = 11;</code>
       */
      public boolean hasLastProgress() {
        return ((bitField0_ & 0x00000400) == 0x00000400);
      }
      /**
       * <code>optional int64 last_progress = 11;</code>
       */
      public long getLastProgress() {
        return lastProgress_;
      }
      /**
       * <code>optional int64 last_progress = 11;</code>
       */
      public Builder setLastProgress(long value) {
        bitField0_ |= 0x00000400;
        lastProgress_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 last_progress = 11;</code>
       */
      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 {
        return new MinorFragmentProfile(input, extensionRegistry);
      }
    };

    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>
     */
    boolean hasOperatorId();
    /**
     * <code>optional int32 operator_id = 3;</code>
     */
    int getOperatorId();

    /**
     * <code>optional int32 operator_type = 4;</code>
     */
    boolean hasOperatorType();
    /**
     * <code>optional int32 operator_type = 4;</code>
     */
    int getOperatorType();

    /**
     * <code>optional int64 setup_nanos = 5;</code>
     */
    boolean hasSetupNanos();
    /**
     * <code>optional int64 setup_nanos = 5;</code>
     */
    long getSetupNanos();

    /**
     * <code>optional int64 process_nanos = 6;</code>
     */
    boolean hasProcessNanos();
    /**
     * <code>optional int64 process_nanos = 6;</code>
     */
    long getProcessNanos();

    /**
     * <code>optional int64 peak_local_memory_allocated = 7;</code>
     */
    boolean hasPeakLocalMemoryAllocated();
    /**
     * <code>optional int64 peak_local_memory_allocated = 7;</code>
     */
    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>
     */
    boolean hasWaitNanos();
    /**
     * <code>optional int64 wait_nanos = 9;</code>
     */
    long getWaitNanos();
  }
  /**
   * 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();
      operatorId_ = 0;
      operatorType_ = 0;
      setupNanos_ = 0L;
      processNanos_ = 0L;
      peakLocalMemoryAllocated_ = 0L;
      metric_ = java.util.Collections.emptyList();
      waitNanos_ = 0L;
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private OperatorProfile(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 10: {
              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
                inputProfile_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserBitShared.StreamProfile>();
                mutable_bitField0_ |= 0x00000001;
              }
              inputProfile_.add(
                  input.readMessage(org.apache.drill.exec.proto.UserBitShared.StreamProfile.PARSER, extensionRegistry));
              break;
            }
            case 24: {
              bitField0_ |= 0x00000001;
              operatorId_ = input.readInt32();
              break;
            }
            case 32: {
              bitField0_ |= 0x00000002;
              operatorType_ = input.readInt32();
              break;
            }
            case 40: {
              bitField0_ |= 0x00000004;
              setupNanos_ = input.readInt64();
              break;
            }
            case 48: {
              bitField0_ |= 0x00000008;
              processNanos_ = input.readInt64();
              break;
            }
            case 56: {
              bitField0_ |= 0x00000010;
              peakLocalMemoryAllocated_ = input.readInt64();
              break;
            }
            case 66: {
              if (!((mutable_bitField0_ & 0x00000040) == 0x00000040)) {
                metric_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserBitShared.MetricValue>();
                mutable_bitField0_ |= 0x00000040;
              }
              metric_.add(
                  input.readMessage(org.apache.drill.exec.proto.UserBitShared.MetricValue.PARSER, extensionRegistry));
              break;
            }
            case 72: {
              bitField0_ |= 0x00000020;
              waitNanos_ = input.readInt64();
              break;
            }
            default: {
              if (!parseUnknownField(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
          inputProfile_ = java.util.Collections.unmodifiableList(inputProfile_);
        }
        if (((mutable_bitField0_ & 0x00000040) == 0x00000040)) {
          metric_ = java.util.Collections.unmodifiableList(metric_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    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>
     */
    public java.util.List<org.apache.drill.exec.proto.UserBitShared.StreamProfile> getInputProfileList() {
      return inputProfile_;
    }
    /**
     * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
     */
    public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.StreamProfileOrBuilder> 
        getInputProfileOrBuilderList() {
      return inputProfile_;
    }
    /**
     * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
     */
    public int getInputProfileCount() {
      return inputProfile_.size();
    }
    /**
     * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
     */
    public org.apache.drill.exec.proto.UserBitShared.StreamProfile getInputProfile(int index) {
      return inputProfile_.get(index);
    }
    /**
     * <code>repeated .exec.shared.StreamProfile input_profile = 1;</code>
     */
    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>
     */
    public boolean hasOperatorId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional int32 operator_id = 3;</code>
     */
    public int getOperatorId() {
      return operatorId_;
    }

    public static final int OPERATOR_TYPE_FIELD_NUMBER = 4;
    private int operatorType_;
    /**
     * <code>optional int32 operator_type = 4;</code>
     */
    public boolean hasOperatorType() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional int32 operator_type = 4;</code>
     */
    public int getOperatorType() {
      return operatorType_;
    }

    public static final int SETUP_NANOS_FIELD_NUMBER = 5;
    private long setupNanos_;
    /**
     * <code>optional int64 setup_nanos = 5;</code>
     */
    public boolean hasSetupNanos() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional int64 setup_nanos = 5;</code>
     */
    public long getSetupNanos() {
      return setupNanos_;
    }

    public static final int PROCESS_NANOS_FIELD_NUMBER = 6;
    private long processNanos_;
    /**
     * <code>optional int64 process_nanos = 6;</code>
     */
    public boolean hasProcessNanos() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>optional int64 process_nanos = 6;</code>
     */
    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>
     */
    public boolean hasPeakLocalMemoryAllocated() {
      return ((bitField0_ & 0x00000010) == 0x00000010);
    }
    /**
     * <code>optional int64 peak_local_memory_allocated = 7;</code>
     */
    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>
     */
    public java.util.List<org.apache.drill.exec.proto.UserBitShared.MetricValue> getMetricList() {
      return metric_;
    }
    /**
     * <code>repeated .exec.shared.MetricValue metric = 8;</code>
     */
    public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.MetricValueOrBuilder> 
        getMetricOrBuilderList() {
      return metric_;
    }
    /**
     * <code>repeated .exec.shared.MetricValue metric = 8;</code>
     */
    public int getMetricCount() {
      return metric_.size();
    }
    /**
     * <code>repeated .exec.shared.MetricValue metric = 8;</code>
     */
    public org.apache.drill.exec.proto.UserBitShared.MetricValue getMetric(int index) {
      return metric_.get(index);
    }
    /**
     * <code>repeated .exec.shared.MetricValue metric = 8;</code>
     */
    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>
     */
    public boolean hasWaitNanos() {
      return ((bitField0_ & 0x00000020) == 0x00000020);
    }
    /**
     * <code>optional int64 wait_nanos = 9;</code>
     */
    public long getWaitNanos() {
      return waitNanos_;
    }

    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) == 0x00000001)) {
        output.writeInt32(3, operatorId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt32(4, operatorType_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeInt64(5, setupNanos_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeInt64(6, processNanos_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        output.writeInt64(7, peakLocalMemoryAllocated_);
      }
      for (int i = 0; i < metric_.size(); i++) {
        output.writeMessage(8, metric_.get(i));
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        output.writeInt64(9, waitNanos_);
      }
      unknownFields.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) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(3, operatorId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(4, operatorType_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(5, setupNanos_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(6, processNanos_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        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) == 0x00000020)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(9, waitNanos_);
      }
      size += unknownFields.getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.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;

      boolean result = true;
      result = result && getInputProfileList()
          .equals(other.getInputProfileList());
      result = result && (hasOperatorId() == other.hasOperatorId());
      if (hasOperatorId()) {
        result = result && (getOperatorId()
            == other.getOperatorId());
      }
      result = result && (hasOperatorType() == other.hasOperatorType());
      if (hasOperatorType()) {
        result = result && (getOperatorType()
            == other.getOperatorType());
      }
      result = result && (hasSetupNanos() == other.hasSetupNanos());
      if (hasSetupNanos()) {
        result = result && (getSetupNanos()
            == other.getSetupNanos());
      }
      result = result && (hasProcessNanos() == other.hasProcessNanos());
      if (hasProcessNanos()) {
        result = result && (getProcessNanos()
            == other.getProcessNanos());
      }
      result = result && (hasPeakLocalMemoryAllocated() == other.hasPeakLocalMemoryAllocated());
      if (hasPeakLocalMemoryAllocated()) {
        result = result && (getPeakLocalMemoryAllocated()
            == other.getPeakLocalMemoryAllocated());
      }
      result = result && getMetricList()
          .equals(other.getMetricList());
      result = result && (hasWaitNanos() == other.hasWaitNanos());
      if (hasWaitNanos()) {
        result = result && (getWaitNanos()
            == other.getWaitNanos());
      }
      result = result && unknownFields.equals(other.unknownFields);
      return result;
    }

    @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());
      }
      hash = (29 * hash) + unknownFields.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() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getInputProfileFieldBuilder();
          getMetricFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        if (inputProfileBuilder_ == null) {
          inputProfile_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
        } else {
          inputProfileBuilder_.clear();
        }
        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();
          bitField0_ = (bitField0_ & ~0x00000040);
        } else {
          metricBuilder_.clear();
        }
        waitNanos_ = 0L;
        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_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) == 0x00000001)) {
            inputProfile_ = java.util.Collections.unmodifiableList(inputProfile_);
            bitField0_ = (bitField0_ & ~0x00000001);
          }
          result.inputProfile_ = inputProfile_;
        } else {
          result.inputProfile_ = inputProfileBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000001;
        }
        result.operatorId_ = operatorId_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000002;
        }
        result.operatorType_ = operatorType_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000004;
        }
        result.setupNanos_ = setupNanos_;
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000008;
        }
        result.processNanos_ = processNanos_;
        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
          to_bitField0_ |= 0x00000010;
        }
        result.peakLocalMemoryAllocated_ = peakLocalMemoryAllocated_;
        if (metricBuilder_ == null) {
          if (((bitField0_ & 0x00000040) == 0x00000040)) {
            metric_ = java.util.Collections.unmodifiableList(metric_);
            bitField0_ = (bitField0_ & ~0x00000040);
          }
          result.metric_ = metric_;
        } else {
          result.metric_ = metricBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000080) == 0x00000080)) {
          to_bitField0_ |= 0x00000020;
        }
        result.waitNanos_ = waitNanos_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return (Builder) super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return (Builder) super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return (Builder) super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return (Builder) super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) 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());
        }
        this.mergeUnknownFields(other.unknownFields);
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.drill.exec.proto.UserBitShared.OperatorProfile parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.drill.exec.proto.UserBitShared.OperatorProfile) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        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) == 0x00000001)) {
          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) == 0x00000001),
                  getParentForChildren(),
                  isClean());
          inputProfile_ = null;
        }
        return inputProfileBuilder_;
      }

      private int operatorId_ ;
      /**
       * <code>optional int32 operator_id = 3;</code>
       */
      public boolean hasOperatorId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional int32 operator_id = 3;</code>
       */
      public int getOperatorId() {
        return operatorId_;
      }
      /**
       * <code>optional int32 operator_id = 3;</code>
       */
      public Builder setOperatorId(int value) {
        bitField0_ |= 0x00000002;
        operatorId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 operator_id = 3;</code>
       */
      public Builder clearOperatorId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        operatorId_ = 0;
        onChanged();
        return this;
      }

      private int operatorType_ ;
      /**
       * <code>optional int32 operator_type = 4;</code>
       */
      public boolean hasOperatorType() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional int32 operator_type = 4;</code>
       */
      public int getOperatorType() {
        return operatorType_;
      }
      /**
       * <code>optional int32 operator_type = 4;</code>
       */
      public Builder setOperatorType(int value) {
        bitField0_ |= 0x00000004;
        operatorType_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 operator_type = 4;</code>
       */
      public Builder clearOperatorType() {
        bitField0_ = (bitField0_ & ~0x00000004);
        operatorType_ = 0;
        onChanged();
        return this;
      }

      private long setupNanos_ ;
      /**
       * <code>optional int64 setup_nanos = 5;</code>
       */
      public boolean hasSetupNanos() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>optional int64 setup_nanos = 5;</code>
       */
      public long getSetupNanos() {
        return setupNanos_;
      }
      /**
       * <code>optional int64 setup_nanos = 5;</code>
       */
      public Builder setSetupNanos(long value) {
        bitField0_ |= 0x00000008;
        setupNanos_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 setup_nanos = 5;</code>
       */
      public Builder clearSetupNanos() {
        bitField0_ = (bitField0_ & ~0x00000008);
        setupNanos_ = 0L;
        onChanged();
        return this;
      }

      private long processNanos_ ;
      /**
       * <code>optional int64 process_nanos = 6;</code>
       */
      public boolean hasProcessNanos() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      /**
       * <code>optional int64 process_nanos = 6;</code>
       */
      public long getProcessNanos() {
        return processNanos_;
      }
      /**
       * <code>optional int64 process_nanos = 6;</code>
       */
      public Builder setProcessNanos(long value) {
        bitField0_ |= 0x00000010;
        processNanos_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 process_nanos = 6;</code>
       */
      public Builder clearProcessNanos() {
        bitField0_ = (bitField0_ & ~0x00000010);
        processNanos_ = 0L;
        onChanged();
        return this;
      }

      private long peakLocalMemoryAllocated_ ;
      /**
       * <code>optional int64 peak_local_memory_allocated = 7;</code>
       */
      public boolean hasPeakLocalMemoryAllocated() {
        return ((bitField0_ & 0x00000020) == 0x00000020);
      }
      /**
       * <code>optional int64 peak_local_memory_allocated = 7;</code>
       */
      public long getPeakLocalMemoryAllocated() {
        return peakLocalMemoryAllocated_;
      }
      /**
       * <code>optional int64 peak_local_memory_allocated = 7;</code>
       */
      public Builder setPeakLocalMemoryAllocated(long value) {
        bitField0_ |= 0x00000020;
        peakLocalMemoryAllocated_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 peak_local_memory_allocated = 7;</code>
       */
      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) == 0x00000040)) {
          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) == 0x00000040),
                  getParentForChildren(),
                  isClean());
          metric_ = null;
        }
        return metricBuilder_;
      }

      private long waitNanos_ ;
      /**
       * <code>optional int64 wait_nanos = 9;</code>
       */
      public boolean hasWaitNanos() {
        return ((bitField0_ & 0x00000080) == 0x00000080);
      }
      /**
       * <code>optional int64 wait_nanos = 9;</code>
       */
      public long getWaitNanos() {
        return waitNanos_;
      }
      /**
       * <code>optional int64 wait_nanos = 9;</code>
       */
      public Builder setWaitNanos(long value) {
        bitField0_ |= 0x00000080;
        waitNanos_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 wait_nanos = 9;</code>
       */
      public Builder clearWaitNanos() {
        bitField0_ = (bitField0_ & ~0x00000080);
        waitNanos_ = 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.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 {
        return new OperatorProfile(input, extensionRegistry);
      }
    };

    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>
     */
    boolean hasRecords();
    /**
     * <code>optional int64 records = 1;</code>
     */
    long getRecords();

    /**
     * <code>optional int64 batches = 2;</code>
     */
    boolean hasBatches();
    /**
     * <code>optional int64 batches = 2;</code>
     */
    long getBatches();

    /**
     * <code>optional int64 schemas = 3;</code>
     */
    boolean hasSchemas();
    /**
     * <code>optional int64 schemas = 3;</code>
     */
    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() {
      records_ = 0L;
      batches_ = 0L;
      schemas_ = 0L;
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private StreamProfile(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 8: {
              bitField0_ |= 0x00000001;
              records_ = input.readInt64();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              batches_ = input.readInt64();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              schemas_ = input.readInt64();
              break;
            }
            default: {
              if (!parseUnknownField(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.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>
     */
    public boolean hasRecords() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional int64 records = 1;</code>
     */
    public long getRecords() {
      return records_;
    }

    public static final int BATCHES_FIELD_NUMBER = 2;
    private long batches_;
    /**
     * <code>optional int64 batches = 2;</code>
     */
    public boolean hasBatches() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional int64 batches = 2;</code>
     */
    public long getBatches() {
      return batches_;
    }

    public static final int SCHEMAS_FIELD_NUMBER = 3;
    private long schemas_;
    /**
     * <code>optional int64 schemas = 3;</code>
     */
    public boolean hasSchemas() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional int64 schemas = 3;</code>
     */
    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) == 0x00000001)) {
        output.writeInt64(1, records_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt64(2, batches_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeInt64(3, schemas_);
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(1, records_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, batches_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(3, schemas_);
      }
      size += unknownFields.getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.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;

      boolean result = true;
      result = result && (hasRecords() == other.hasRecords());
      if (hasRecords()) {
        result = result && (getRecords()
            == other.getRecords());
      }
      result = result && (hasBatches() == other.hasBatches());
      if (hasBatches()) {
        result = result && (getBatches()
            == other.getBatches());
      }
      result = result && (hasSchemas() == other.hasSchemas());
      if (hasSchemas()) {
        result = result && (getSchemas()
            == other.getSchemas());
      }
      result = result && unknownFields.equals(other.unknownFields);
      return result;
    }

    @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) + unknownFields.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() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        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) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.records_ = records_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.batches_ = batches_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.schemas_ = schemas_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return (Builder) super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return (Builder) super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return (Builder) super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return (Builder) super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) 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.unknownFields);
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.drill.exec.proto.UserBitShared.StreamProfile parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.drill.exec.proto.UserBitShared.StreamProfile) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private long records_ ;
      /**
       * <code>optional int64 records = 1;</code>
       */
      public boolean hasRecords() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional int64 records = 1;</code>
       */
      public long getRecords() {
        return records_;
      }
      /**
       * <code>optional int64 records = 1;</code>
       */
      public Builder setRecords(long value) {
        bitField0_ |= 0x00000001;
        records_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 records = 1;</code>
       */
      public Builder clearRecords() {
        bitField0_ = (bitField0_ & ~0x00000001);
        records_ = 0L;
        onChanged();
        return this;
      }

      private long batches_ ;
      /**
       * <code>optional int64 batches = 2;</code>
       */
      public boolean hasBatches() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional int64 batches = 2;</code>
       */
      public long getBatches() {
        return batches_;
      }
      /**
       * <code>optional int64 batches = 2;</code>
       */
      public Builder setBatches(long value) {
        bitField0_ |= 0x00000002;
        batches_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 batches = 2;</code>
       */
      public Builder clearBatches() {
        bitField0_ = (bitField0_ & ~0x00000002);
        batches_ = 0L;
        onChanged();
        return this;
      }

      private long schemas_ ;
      /**
       * <code>optional int64 schemas = 3;</code>
       */
      public boolean hasSchemas() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional int64 schemas = 3;</code>
       */
      public long getSchemas() {
        return schemas_;
      }
      /**
       * <code>optional int64 schemas = 3;</code>
       */
      public Builder setSchemas(long value) {
        bitField0_ |= 0x00000004;
        schemas_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 schemas = 3;</code>
       */
      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 {
        return new StreamProfile(input, extensionRegistry);
      }
    };

    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>
     */
    boolean hasMetricId();
    /**
     * <code>optional int32 metric_id = 1;</code>
     */
    int getMetricId();

    /**
     * <code>optional int64 long_value = 2;</code>
     */
    boolean hasLongValue();
    /**
     * <code>optional int64 long_value = 2;</code>
     */
    long getLongValue();

    /**
     * <code>optional double double_value = 3;</code>
     */
    boolean hasDoubleValue();
    /**
     * <code>optional double double_value = 3;</code>
     */
    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() {
      metricId_ = 0;
      longValue_ = 0L;
      doubleValue_ = 0D;
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private MetricValue(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 8: {
              bitField0_ |= 0x00000001;
              metricId_ = input.readInt32();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              longValue_ = input.readInt64();
              break;
            }
            case 25: {
              bitField0_ |= 0x00000004;
              doubleValue_ = input.readDouble();
              break;
            }
            default: {
              if (!parseUnknownField(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.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>
     */
    public boolean hasMetricId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional int32 metric_id = 1;</code>
     */
    public int getMetricId() {
      return metricId_;
    }

    public static final int LONG_VALUE_FIELD_NUMBER = 2;
    private long longValue_;
    /**
     * <code>optional int64 long_value = 2;</code>
     */
    public boolean hasLongValue() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional int64 long_value = 2;</code>
     */
    public long getLongValue() {
      return longValue_;
    }

    public static final int DOUBLE_VALUE_FIELD_NUMBER = 3;
    private double doubleValue_;
    /**
     * <code>optional double double_value = 3;</code>
     */
    public boolean hasDoubleValue() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional double double_value = 3;</code>
     */
    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) == 0x00000001)) {
        output.writeInt32(1, metricId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt64(2, longValue_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeDouble(3, doubleValue_);
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(1, metricId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, longValue_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeDoubleSize(3, doubleValue_);
      }
      size += unknownFields.getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.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;

      boolean result = true;
      result = result && (hasMetricId() == other.hasMetricId());
      if (hasMetricId()) {
        result = result && (getMetricId()
            == other.getMetricId());
      }
      result = result && (hasLongValue() == other.hasLongValue());
      if (hasLongValue()) {
        result = result && (getLongValue()
            == other.getLongValue());
      }
      result = result && (hasDoubleValue() == other.hasDoubleValue());
      if (hasDoubleValue()) {
        result = result && (
            java.lang.Double.doubleToLongBits(getDoubleValue())
            == java.lang.Double.doubleToLongBits(
                other.getDoubleValue()));
      }
      result = result && unknownFields.equals(other.unknownFields);
      return result;
    }

    @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) + unknownFields.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() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        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) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.metricId_ = metricId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.longValue_ = longValue_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.doubleValue_ = doubleValue_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return (Builder) super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return (Builder) super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return (Builder) super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return (Builder) super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) 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.unknownFields);
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.drill.exec.proto.UserBitShared.MetricValue parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.drill.exec.proto.UserBitShared.MetricValue) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private int metricId_ ;
      /**
       * <code>optional int32 metric_id = 1;</code>
       */
      public boolean hasMetricId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional int32 metric_id = 1;</code>
       */
      public int getMetricId() {
        return metricId_;
      }
      /**
       * <code>optional int32 metric_id = 1;</code>
       */
      public Builder setMetricId(int value) {
        bitField0_ |= 0x00000001;
        metricId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 metric_id = 1;</code>
       */
      public Builder clearMetricId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        metricId_ = 0;
        onChanged();
        return this;
      }

      private long longValue_ ;
      /**
       * <code>optional int64 long_value = 2;</code>
       */
      public boolean hasLongValue() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional int64 long_value = 2;</code>
       */
      public long getLongValue() {
        return longValue_;
      }
      /**
       * <code>optional int64 long_value = 2;</code>
       */
      public Builder setLongValue(long value) {
        bitField0_ |= 0x00000002;
        longValue_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 long_value = 2;</code>
       */
      public Builder clearLongValue() {
        bitField0_ = (bitField0_ & ~0x00000002);
        longValue_ = 0L;
        onChanged();
        return this;
      }

      private double doubleValue_ ;
      /**
       * <code>optional double double_value = 3;</code>
       */
      public boolean hasDoubleValue() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional double double_value = 3;</code>
       */
      public double getDoubleValue() {
        return doubleValue_;
      }
      /**
       * <code>optional double double_value = 3;</code>
       */
      public Builder setDoubleValue(double value) {
        bitField0_ |= 0x00000004;
        doubleValue_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional double double_value = 3;</code>
       */
      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 {
        return new MetricValue(input, extensionRegistry);
      }
    };

    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
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private Registry(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 10: {
              if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
                jar_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserBitShared.Jar>();
                mutable_bitField0_ |= 0x00000001;
              }
              jar_.add(
                  input.readMessage(org.apache.drill.exec.proto.UserBitShared.Jar.PARSER, extensionRegistry));
              break;
            }
            default: {
              if (!parseUnknownField(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
          jar_ = java.util.Collections.unmodifiableList(jar_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    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>
     */
    public java.util.List<org.apache.drill.exec.proto.UserBitShared.Jar> getJarList() {
      return jar_;
    }
    /**
     * <code>repeated .exec.shared.Jar jar = 1;</code>
     */
    public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.JarOrBuilder> 
        getJarOrBuilderList() {
      return jar_;
    }
    /**
     * <code>repeated .exec.shared.Jar jar = 1;</code>
     */
    public int getJarCount() {
      return jar_.size();
    }
    /**
     * <code>repeated .exec.shared.Jar jar = 1;</code>
     */
    public org.apache.drill.exec.proto.UserBitShared.Jar getJar(int index) {
      return jar_.get(index);
    }
    /**
     * <code>repeated .exec.shared.Jar jar = 1;</code>
     */
    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));
      }
      unknownFields.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 += unknownFields.getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.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;

      boolean result = true;
      result = result && getJarList()
          .equals(other.getJarList());
      result = result && unknownFields.equals(other.unknownFields);
      return result;
    }

    @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) + unknownFields.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() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getJarFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        if (jarBuilder_ == null) {
          jar_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
        } else {
          jarBuilder_.clear();
        }
        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) == 0x00000001)) {
            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 (Builder) super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return (Builder) super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return (Builder) super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return (Builder) super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) 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.unknownFields);
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.drill.exec.proto.UserBitShared.Registry parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.drill.exec.proto.UserBitShared.Registry) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        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) == 0x00000001)) {
          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) == 0x00000001),
                  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 {
        return new Registry(input, extensionRegistry);
      }
    };

    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>
     */
    boolean hasName();
    /**
     * <code>optional string name = 1;</code>
     */
    java.lang.String getName();
    /**
     * <code>optional string name = 1;</code>
     */
    com.google.protobuf.ByteString
        getNameBytes();

    /**
     * <code>repeated string function_signature = 2;</code>
     */
    java.util.List<java.lang.String>
        getFunctionSignatureList();
    /**
     * <code>repeated string function_signature = 2;</code>
     */
    int getFunctionSignatureCount();
    /**
     * <code>repeated string function_signature = 2;</code>
     */
    java.lang.String getFunctionSignature(int index);
    /**
     * <code>repeated string function_signature = 2;</code>
     */
    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
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private Jar(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 10: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00000001;
              name_ = bs;
              break;
            }
            case 18: {
              com.google.protobuf.ByteString bs = input.readBytes();
              if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
                functionSignature_ = new com.google.protobuf.LazyStringArrayList();
                mutable_bitField0_ |= 0x00000002;
              }
              functionSignature_.add(bs);
              break;
            }
            default: {
              if (!parseUnknownField(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
          functionSignature_ = functionSignature_.getUnmodifiableView();
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    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>
     */
    public boolean hasName() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional string name = 1;</code>
     */
    public java.lang.String getName() {
      java.lang.Object ref = name_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          name_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string name = 1;</code>
     */
    public com.google.protobuf.ByteString
        getNameBytes() {
      java.lang.Object ref = name_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        name_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int FUNCTION_SIGNATURE_FIELD_NUMBER = 2;
    private com.google.protobuf.LazyStringList functionSignature_;
    /**
     * <code>repeated string function_signature = 2;</code>
     */
    public com.google.protobuf.ProtocolStringList
        getFunctionSignatureList() {
      return functionSignature_;
    }
    /**
     * <code>repeated string function_signature = 2;</code>
     */
    public int getFunctionSignatureCount() {
      return functionSignature_.size();
    }
    /**
     * <code>repeated string function_signature = 2;</code>
     */
    public java.lang.String getFunctionSignature(int index) {
      return functionSignature_.get(index);
    }
    /**
     * <code>repeated string function_signature = 2;</code>
     */
    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) == 0x00000001)) {
        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));
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        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 += unknownFields.getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.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;

      boolean result = true;
      result = result && (hasName() == other.hasName());
      if (hasName()) {
        result = result && getName()
            .equals(other.getName());
      }
      result = result && getFunctionSignatureList()
          .equals(other.getFunctionSignatureList());
      result = result && unknownFields.equals(other.unknownFields);
      return result;
    }

    @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) + unknownFields.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() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        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) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.name_ = name_;
        if (((bitField0_ & 0x00000002) == 0x00000002)) {
          functionSignature_ = functionSignature_.getUnmodifiableView();
          bitField0_ = (bitField0_ & ~0x00000002);
        }
        result.functionSignature_ = functionSignature_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return (Builder) super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return (Builder) super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return (Builder) super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return (Builder) super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) 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.unknownFields);
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.drill.exec.proto.UserBitShared.Jar parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.drill.exec.proto.UserBitShared.Jar) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private java.lang.Object name_ = "";
      /**
       * <code>optional string name = 1;</code>
       */
      public boolean hasName() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional string name = 1;</code>
       */
      public java.lang.String getName() {
        java.lang.Object ref = name_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            name_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string name = 1;</code>
       */
      public com.google.protobuf.ByteString
          getNameBytes() {
        java.lang.Object ref = name_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          name_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string name = 1;</code>
       */
      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>
       */
      public Builder clearName() {
        bitField0_ = (bitField0_ & ~0x00000001);
        name_ = getDefaultInstance().getName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string name = 1;</code>
       */
      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) == 0x00000002)) {
          functionSignature_ = new com.google.protobuf.LazyStringArrayList(functionSignature_);
          bitField0_ |= 0x00000002;
         }
      }
      /**
       * <code>repeated string function_signature = 2;</code>
       */
      public com.google.protobuf.ProtocolStringList
          getFunctionSignatureList() {
        return functionSignature_.getUnmodifiableView();
      }
      /**
       * <code>repeated string function_signature = 2;</code>
       */
      public int getFunctionSignatureCount() {
        return functionSignature_.size();
      }
      /**
       * <code>repeated string function_signature = 2;</code>
       */
      public java.lang.String getFunctionSignature(int index) {
        return functionSignature_.get(index);
      }
      /**
       * <code>repeated string function_signature = 2;</code>
       */
      public com.google.protobuf.ByteString
          getFunctionSignatureBytes(int index) {
        return functionSignature_.getByteString(index);
      }
      /**
       * <code>repeated string function_signature = 2;</code>
       */
      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>
       */
      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>
       */
      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>
       */
      public Builder clearFunctionSignature() {
        functionSignature_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000002);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string function_signature = 2;</code>
       */
      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 {
        return new Jar(input, extensionRegistry);
      }
    };

    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>
     */
    boolean hasMechanism();
    /**
     * <code>optional string mechanism = 1;</code>
     */
    java.lang.String getMechanism();
    /**
     * <code>optional string mechanism = 1;</code>
     */
    com.google.protobuf.ByteString
        getMechanismBytes();

    /**
     * <code>optional bytes data = 2;</code>
     */
    boolean hasData();
    /**
     * <code>optional bytes data = 2;</code>
     */
    com.google.protobuf.ByteString getData();

    /**
     * <code>optional .exec.shared.SaslStatus status = 3;</code>
     */
    boolean hasStatus();
    /**
     * <code>optional .exec.shared.SaslStatus status = 3;</code>
     */
    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
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private SaslMessage(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 10: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00000001;
              mechanism_ = bs;
              break;
            }
            case 18: {
              bitField0_ |= 0x00000002;
              data_ = input.readBytes();
              break;
            }
            case 24: {
              int rawValue = input.readEnum();
                @SuppressWarnings("deprecation")
              org.apache.drill.exec.proto.UserBitShared.SaslStatus value = org.apache.drill.exec.proto.UserBitShared.SaslStatus.valueOf(rawValue);
              if (value == null) {
                unknownFields.mergeVarintField(3, rawValue);
              } else {
                bitField0_ |= 0x00000004;
                status_ = rawValue;
              }
              break;
            }
            default: {
              if (!parseUnknownField(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.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>
     */
    public boolean hasMechanism() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>optional string mechanism = 1;</code>
     */
    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>
     */
    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>
     */
    public boolean hasData() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>optional bytes data = 2;</code>
     */
    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>
     */
    public boolean hasStatus() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>optional .exec.shared.SaslStatus status = 3;</code>
     */
    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) == 0x00000001)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, mechanism_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBytes(2, data_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeEnum(3, status_);
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, mechanism_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(2, data_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(3, status_);
      }
      size += unknownFields.getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.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;

      boolean result = true;
      result = result && (hasMechanism() == other.hasMechanism());
      if (hasMechanism()) {
        result = result && getMechanism()
            .equals(other.getMechanism());
      }
      result = result && (hasData() == other.hasData());
      if (hasData()) {
        result = result && getData()
            .equals(other.getData());
      }
      result = result && (hasStatus() == other.hasStatus());
      if (hasStatus()) {
        result = result && status_ == other.status_;
      }
      result = result && unknownFields.equals(other.unknownFields);
      return result;
    }

    @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) + unknownFields.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() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        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) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.mechanism_ = mechanism_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.data_ = data_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.status_ = status_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return (Builder) super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return (Builder) super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return (Builder) super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return (Builder) super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return (Builder) 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.unknownFields);
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.drill.exec.proto.UserBitShared.SaslMessage parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.drill.exec.proto.UserBitShared.SaslMessage) e.getUnfinishedMessage();
          throw e.unwrapIOException();
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      private java.lang.Object mechanism_ = "";
      /**
       * <code>optional string mechanism = 1;</code>
       */
      public boolean hasMechanism() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>optional string mechanism = 1;</code>
       */
      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>
       */
      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>
       */
      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>
       */
      public Builder clearMechanism() {
        bitField0_ = (bitField0_ & ~0x00000001);
        mechanism_ = getDefaultInstance().getMechanism();
        onChanged();
        return this;
      }
      /**
       * <code>optional string mechanism = 1;</code>
       */
      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>
       */
      public boolean hasData() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>optional bytes data = 2;</code>
       */
      public com.google.protobuf.ByteString getData() {
        return data_;
      }
      /**
       * <code>optional bytes data = 2;</code>
       */
      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>
       */
      public Builder clearData() {
        bitField0_ = (bitField0_ & ~0x00000002);
        data_ = getDefaultInstance().getData();
        onChanged();
        return this;
      }

      private int status_ = 0;
      /**
       * <code>optional .exec.shared.SaslStatus status = 3;</code>
       */
      public boolean hasStatus() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>optional .exec.shared.SaslStatus status = 3;</code>
       */
      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>
       */
      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>
       */
      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 {
        return new SaslMessage(input, extensionRegistry);
      }
    };

    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\"\355\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\"\362\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\"\246\001\n\020ExceptionWrapper" +
      "\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%.exec.shared.St" +
      "ackTraceElementWrapper\022,\n\005cause\030\004 \001(\0132\035." +
      "exec.shared.ExceptionWrapper\"\205\001\n\030StackTr" +
      "aceElementWrapper\022\022\n\nclass_name\030\001 \001(\t\022\021\n" +
      "\tfile_name\030\002 \001(\t\022\023\n\013line_number\030\003 \001(\005\022\023\n" +
      "\013method_name\030\004 \001(\t\022\030\n\020is_native_method\030\005" +
      " \001(\010\"\\\n\014ParsingError\022\024\n\014start_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\016RecordBatchDef\022\024\n" +
      "\014record_count\030\001 \001(\005\022+\n\005field\030\002 \003(\0132\034.exe" +
      "c.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\010NamePart\022(\n\004type\030\001 " +
      "\001(\0162\032.exec.shared.NamePart.Type\022\014\n\004name\030" +
      "\002 \001(\t\022$\n\005child\030\003 \001(\0132\025.exec.shared.NameP" +
      "art\"\033\n\004Type\022\010\n\004NAME\020\000\022\t\n\005ARRAY\020\001\"\324\001\n\017Ser" +
      "ializedField\022%\n\nmajor_type\030\001 \001(\0132\021.commo" +
      "n.MajorType\022(\n\tname_part\030\002 \001(\0132\025.exec.sh" +
      "ared.NamePart\022+\n\005child\030\003 \003(\0132\034.exec.shar" +
      "ed.SerializedField\022\023\n\013value_count\030\004 \001(\005\022" +
      "\027\n\017var_byte_length\030\005 \001(\005\022\025\n\rbuffer_lengt" +
      "h\030\007 \001(\005\"7\n\nNodeStatus\022\017\n\007node_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.Quer" +
      "yResult.QueryState\022&\n\010query_id\030\002 \001(\0132\024.e" +
      "xec.shared.QueryId\022(\n\005error\030\003 \003(\0132\031.exec" +
      ".shared.DrillPBError\"\227\001\n\nQueryState\022\014\n\010S" +
      "TARTING\020\000\022\013\n\007RUNNING\020\001\022\r\n\tCOMPLETED\020\002\022\014\n" +
      "\010CANCELED\020\003\022\n\n\006FAILED\020\004\022\032\n\026CANCELLATION_" +
      "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_coun" +
      "t\030\002 \001(\005\022(\n\003def\030\003 \001(\0132\033.exec.shared.Recor" +
      "dBatchDef\022\033\n\023affected_rows_count\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.shared.QueryRes" +
      "ult.QueryState\022\017\n\004user\030\004 \001(\t:\001-\022\'\n\007forem" +
      "an\030\005 \001(\0132\026.exec.DrillbitEndpoint\022\024\n\014opti" +
      "ons_json\030\006 \001(\t\022\022\n\ntotal_cost\030\007 \001(\001\022\025\n\nqu" +
      "eue_name\030\010 \001(\t:\001-\"\306\004\n\014QueryProfile\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.DrillbitEndp" +
      "oint\0222\n\005state\030\010 \001(\0162#.exec.shared.QueryR" +
      "esult.QueryState\022\027\n\017total_fragments\030\t \001(" +
      "\005\022\032\n\022finished_fragments\030\n \001(\005\022;\n\020fragmen" +
      "t_profile\030\013 \003(\0132!.exec.shared.MajorFragm" +
      "entProfile\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\010error_id\030\017 \001" +
      "(\t\022\022\n\nerror_node\030\020 \001(\t\022\024\n\014options_json\030\021" +
      " \001(\t\022\017\n\007planEnd\030\022 \001(\003\022\024\n\014queueWaitEnd\030\023 " +
      "\001(\003\022\022\n\ntotal_cost\030\024 \001(\001\022\025\n\nqueue_name\030\025 " +
      "\001(\t:\001-\022\017\n\007queryId\030\026 \001(\t\022\021\n\tautoLimit\030\027 \001" +
      "(\005\"t\n\024MajorFragmentProfile\022\031\n\021major_frag" +
      "ment_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(\016" +
      "2\032.exec.shared.FragmentState\022(\n\005error\030\002 " +
      "\001(\0132\031.exec.shared.DrillPBError\022\031\n\021minor_" +
      "fragment_id\030\003 \001(\005\0226\n\020operator_profile\030\004 " +
      "\003(\0132\034.exec.shared.OperatorProfile\022\022\n\nsta" +
      "rt_time\030\005 \001(\003\022\020\n\010end_time\030\006 \001(\003\022\023\n\013memor" +
      "y_used\030\007 \001(\003\022\027\n\017max_memory_used\030\010 \001(\003\022(\n" +
      "\010endpoint\030\t \001(\0132\026.exec.DrillbitEndpoint\022" +
      "\023\n\013last_update\030\n \001(\003\022\025\n\rlast_progress\030\013 " +
      "\001(\003\"\377\001\n\017OperatorProfile\0221\n\rinput_profile" +
      "\030\001 \003(\0132\032.exec.shared.StreamProfile\022\023\n\013op" +
      "erator_id\030\003 \001(\005\022\025\n\roperator_type\030\004 \001(\005\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.MetricValu" +
      "e\022\022\n\nwait_nanos\030\t \001(\003\"B\n\rStreamProfile\022\017" +
      "\n\007records\030\001 \001(\003\022\017\n\007batches\030\002 \001(\003\022\017\n\007sche" +
      "mas\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\010Registry\022\035\n\003jar\030\001 \003(\0132\020.exec.sh" +
      "ared.Jar\"/\n\003Jar\022\014\n\004name\030\001 \001(\t\022\032\n\022functio" +
      "n_signature\030\002 \003(\t\"W\n\013SaslMessage\022\021\n\tmech" +
      "anism\030\001 \001(\t\022\014\n\004data\030\002 \001(\014\022\'\n\006status\030\003 \001(" +
      "\0162\027.exec.shared.SaslStatus*5\n\nRpcChannel" +
      "\022\017\n\013BIT_CONTROL\020\000\022\014\n\010BIT_DATA\020\001\022\010\n\004USER\020" +
      "\002*V\n\tQueryType\022\007\n\003SQL\020\001\022\013\n\007LOGICAL\020\002\022\014\n\010" +
      "PHYSICAL\020\003\022\r\n\tEXECUTION\020\004\022\026\n\022PREPARED_ST" +
      "ATEMENT\020\005*\207\001\n\rFragmentState\022\013\n\007SENDING\020\000" +
      "\022\027\n\023AWAITING_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\026CANCELLATION_REQUESTED\020\006*\344\n\n\020CoreOper" +
      "atorType\022\021\n\rSINGLE_SENDER\020\000\022\024\n\020BROADCAST" +
      "_SENDER\020\001\022\n\n\006FILTER\020\002\022\022\n\016HASH_AGGREGATE\020" +
      "\003\022\r\n\tHASH_JOIN\020\004\022\016\n\nMERGE_JOIN\020\005\022\031\n\025HASH" +
      "_PARTITION_SENDER\020\006\022\t\n\005LIMIT\020\007\022\024\n\020MERGIN" +
      "G_RECEIVER\020\010\022\034\n\030ORDERED_PARTITION_SENDER" +
      "\020\t\022\013\n\007PROJECT\020\n\022\026\n\022UNORDERED_RECEIVER\020\013\022" +
      "\032\n\026RANGE_PARTITION_SENDER\020\014\022\n\n\006SCREEN\020\r\022" +
      "\034\n\030SELECTION_VECTOR_REMOVER\020\016\022\027\n\023STREAMI" +
      "NG_AGGREGATE\020\017\022\016\n\nTOP_N_SORT\020\020\022\021\n\rEXTERN" +
      "AL_SORT\020\021\022\t\n\005TRACE\020\022\022\t\n\005UNION\020\023\022\014\n\010OLD_S" +
      "ORT\020\024\022\032\n\026PARQUET_ROW_GROUP_SCAN\020\025\022\021\n\rHIV" +
      "E_SUB_SCAN\020\026\022\025\n\021SYSTEM_TABLE_SCAN\020\027\022\021\n\rM" +
      "OCK_SUB_SCAN\020\030\022\022\n\016PARQUET_WRITER\020\031\022\023\n\017DI" +
      "RECT_SUB_SCAN\020\032\022\017\n\013TEXT_WRITER\020\033\022\021\n\rTEXT" +
      "_SUB_SCAN\020\034\022\021\n\rJSON_SUB_SCAN\020\035\022\030\n\024INFO_S" +
      "CHEMA_SUB_SCAN\020\036\022\023\n\017COMPLEX_TO_JSON\020\037\022\025\n" +
      "\021PRODUCER_CONSUMER\020 \022\022\n\016HBASE_SUB_SCAN\020!" +
      "\022\n\n\006WINDOW\020\"\022\024\n\020NESTED_LOOP_JOIN\020#\022\021\n\rAV" +
      "RO_SUB_SCAN\020$\022\021\n\rPCAP_SUB_SCAN\020%\022\022\n\016KAFK" +
      "A_SUB_SCAN\020&\022\021\n\rKUDU_SUB_SCAN\020\'\022\013\n\007FLATT" +
      "EN\020(\022\020\n\014LATERAL_JOIN\020)\022\n\n\006UNNEST\020*\022,\n(HI" +
      "VE_DRILL_NATIVE_PARQUET_ROW_GROUP_SCAN\020+" +
      "\022\r\n\tJDBC_SCAN\020,\022\022\n\016REGEX_SUB_SCAN\020-\022\023\n\017M" +
      "APRDB_SUB_SCAN\020.\022\022\n\016MONGO_SUB_SCAN\020/\022\017\n\013" +
      "KUDU_WRITER\0200\022\026\n\022OPEN_TSDB_SUB_SCAN\0201\022\017\n" +
      "\013JSON_WRITER\0202\022\026\n\022HTPPD_LOG_SUB_SCAN\0203\022\022" +
      "\n\016IMAGE_SUB_SCAN\0204\022\025\n\021SEQUENCE_SUB_SCAN\020" +
      "5\022\023\n\017PARTITION_LIMIT\0206\022\023\n\017PCAPNG_SUB_SCA" +
      "N\0207\022\022\n\016RUNTIME_FILTER\0208\022\017\n\013ROWKEY_JOIN\0209" +
      "\022\023\n\017SYSLOG_SUB_SCAN\020:\022\030\n\024STATISTICS_AGGR" +
      "EGATE\020;\022\020\n\014UNPIVOT_MAPS\020<\022\024\n\020STATISTICS_" +
      "MERGE\020=\022\021\n\rLTSV_SUB_SCAN\020>\022\021\n\rHDF5_SUB_S" +
      "CAN\020?\022\022\n\016EXCEL_SUB_SCAN\020@\022\020\n\014SHP_SUB_SCA" +
      "N\020A\022\024\n\020METADATA_HANDLER\020B\022\027\n\023METADATA_CO" +
      "NTROLLER\020C*g\n\nSaslStatus\022\020\n\014SASL_UNKNOWN" +
      "\020\000\022\016\n\nSASL_START\020\001\022\024\n\020SASL_IN_PROGRESS\020\002" +
      "\022\020\n\014SASL_SUCCESS\020\003\022\017\n\013SASL_FAILED\020\004B.\n\033o" +
      "rg.apache.drill.exec.protoB\rUserBitShare" +
      "dH\001"
    };
    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
          public com.google.protobuf.ExtensionRegistry assignDescriptors(
              com.google.protobuf.Descriptors.FileDescriptor root) {
            descriptor = root;
            return null;
          }
        };
    com.google.protobuf.Descriptors.FileDescriptor
      .internalBuildGeneratedFileFrom(descriptorData,
        new com.google.protobuf.Descriptors.FileDescriptor[] {
          org.apache.drill.common.types.TypeProtos.getDescriptor(),
          org.apache.drill.exec.proto.CoordinationProtos.getDescriptor(),
          org.apache.drill.exec.proto.SchemaDefProtos.getDescriptor(),
        }, assigner);
    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", });
    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", });
    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)
}
