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

package org.apache.drill.exec.proto;

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

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

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


    public final int getNumber() {
      return value;
    }

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

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

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

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

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

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

    private final int value;

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

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

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

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


    public final int getNumber() {
      return value;
    }

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

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

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

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

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

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

    private final int value;

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

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

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

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


    public final int getNumber() {
      return value;
    }

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

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

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

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

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

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

    private final int value;

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

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

  /**
   * Protobuf enum {@code exec.shared.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>DRUID_SUB_SCAN = 68;</code>
     */
    DRUID_SUB_SCAN(68),
    /**
     * <code>SPSS_SUB_SCAN = 69;</code>
     */
    SPSS_SUB_SCAN(69),
    /**
     * <code>HTTP_SUB_SCAN = 70;</code>
     */
    HTTP_SUB_SCAN(70),
    ;

    /**
     * <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;
    /**
     * <code>DRUID_SUB_SCAN = 68;</code>
     */
    public static final int DRUID_SUB_SCAN_VALUE = 68;
    /**
     * <code>SPSS_SUB_SCAN = 69;</code>
     */
    public static final int SPSS_SUB_SCAN_VALUE = 69;
    /**
     * <code>HTTP_SUB_SCAN = 70;</code>
     */
    public static final int HTTP_SUB_SCAN_VALUE = 70;


    public final int getNumber() {
      return value;
    }

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

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static 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;
        case 68: return DRUID_SUB_SCAN;
        case 69: return SPSS_SUB_SCAN;
        case 70: return HTTP_SUB_SCAN;
        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;
    }

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

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

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

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserBitShared.getDescriptor().getEnumTypes().get(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>
     * @return Whether the userName field is set.
     */
    boolean hasUserName();
    /**
     * <code>optional string user_name = 1;</code>
     * @return The userName.
     */
    java.lang.String getUserName();
    /**
     * <code>optional string user_name = 1;</code>
     * @return The bytes for userName.
     */
    com.google.protobuf.ByteString
        getUserNameBytes();
  }
  /**
   * Protobuf type {@code exec.shared.UserCredentials}
   */
  public  static final class UserCredentials extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.UserCredentials)
      UserCredentialsOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use UserCredentials.newBuilder() to construct.
    private UserCredentials(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private UserCredentials() {
      userName_ = "";
    }

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

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

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

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, userName_);
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, userName_);
      }
      size += 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;

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

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (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) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.userName_ = userName_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserBitShared.UserCredentials) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.UserCredentials)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

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

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


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

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

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

    @java.lang.Deprecated public static final com.google.protobuf.Parser<UserCredentials>
        PARSER = new com.google.protobuf.AbstractParser<UserCredentials>() {
      @java.lang.Override
      public UserCredentials parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        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>
     * @return Whether the part1 field is set.
     */
    boolean hasPart1();
    /**
     * <code>optional sfixed64 part1 = 1;</code>
     * @return The part1.
     */
    long getPart1();

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

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

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    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>
     * @return Whether the part1 field is set.
     */
    public boolean hasPart1() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional sfixed64 part1 = 1;</code>
     * @return The part1.
     */
    public long getPart1() {
      return part1_;
    }

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

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

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeSFixed64(1, part1_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeSFixed64(2, part2_);
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeSFixed64Size(1, part1_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeSFixed64Size(2, part2_);
      }
      size += 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;

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

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (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) != 0)) {
          result.part1_ = part1_;
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.part2_ = part2_;
          to_bitField0_ |= 0x00000002;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserBitShared.QueryId) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.QueryId)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.QueryId other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance()) return this;
        if (other.hasPart1()) {
          setPart1(other.getPart1());
        }
        if (other.hasPart2()) {
          setPart2(other.getPart2());
        }
        this.mergeUnknownFields(other.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>
       * @return Whether the part1 field is set.
       */
      public boolean hasPart1() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional sfixed64 part1 = 1;</code>
       * @return The part1.
       */
      public long getPart1() {
        return part1_;
      }
      /**
       * <code>optional sfixed64 part1 = 1;</code>
       * @param value The part1 to set.
       * @return This builder for chaining.
       */
      public Builder setPart1(long value) {
        bitField0_ |= 0x00000001;
        part1_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional sfixed64 part1 = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearPart1() {
        bitField0_ = (bitField0_ & ~0x00000001);
        part1_ = 0L;
        onChanged();
        return this;
      }

      private long part2_ ;
      /**
       * <code>optional sfixed64 part2 = 2;</code>
       * @return Whether the part2 field is set.
       */
      public boolean hasPart2() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional sfixed64 part2 = 2;</code>
       * @return The part2.
       */
      public long getPart2() {
        return part2_;
      }
      /**
       * <code>optional sfixed64 part2 = 2;</code>
       * @param value The part2 to set.
       * @return This builder for chaining.
       */
      public Builder setPart2(long value) {
        bitField0_ |= 0x00000002;
        part2_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional sfixed64 part2 = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearPart2() {
        bitField0_ = (bitField0_ & ~0x00000002);
        part2_ = 0L;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

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


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

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

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

    @java.lang.Deprecated public static final com.google.protobuf.Parser<QueryId>
        PARSER = new com.google.protobuf.AbstractParser<QueryId>() {
      @java.lang.Override
      public QueryId parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        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>
     * @return Whether the errorId field is set.
     */
    boolean hasErrorId();
    /**
     * <pre>
     * for debug tracing purposes
     * </pre>
     *
     * <code>optional string error_id = 1;</code>
     * @return The errorId.
     */
    java.lang.String getErrorId();
    /**
     * <pre>
     * for debug tracing purposes
     * </pre>
     *
     * <code>optional string error_id = 1;</code>
     * @return The bytes for errorId.
     */
    com.google.protobuf.ByteString
        getErrorIdBytes();

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

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

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

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

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

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

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

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

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

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

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

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

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

      private final int value;

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

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

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

    public static final int ENDPOINT_FIELD_NUMBER = 2;
    private org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint endpoint_;
    /**
     * <code>optional .exec.DrillbitEndpoint endpoint = 2;</code>
     * @return Whether the endpoint field is set.
     */
    public boolean hasEndpoint() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .exec.DrillbitEndpoint endpoint = 2;</code>
     * @return The endpoint.
     */
    public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint getEndpoint() {
      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>
     * @return Whether the errorType field is set.
     */
    public boolean hasErrorType() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional .exec.shared.DrillPBError.ErrorType error_type = 3;</code>
     * @return The errorType.
     */
    public org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType getErrorType() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType result = org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType.valueOf(errorType_);
      return result == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.ErrorType.CONNECTION : result;
    }

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

    public static final int EXCEPTION_FIELD_NUMBER = 5;
    private org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper exception_;
    /**
     * <code>optional .exec.shared.ExceptionWrapper exception = 5;</code>
     * @return Whether the exception field is set.
     */
    public boolean hasException() {
      return ((bitField0_ & 0x00000010) != 0);
    }
    /**
     * <code>optional .exec.shared.ExceptionWrapper exception = 5;</code>
     * @return The exception.
     */
    public org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper getException() {
      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) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, errorId_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeMessage(2, getEndpoint());
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeEnum(3, errorType_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 4, message_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        output.writeMessage(5, getException());
      }
      for (int i = 0; i < parsingError_.size(); i++) {
        output.writeMessage(6, parsingError_.get(i));
      }
      unknownFields.writeTo(output);
    }

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

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

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

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (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) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.errorId_ = errorId_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          if (endpointBuilder_ == null) {
            result.endpoint_ = endpoint_;
          } else {
            result.endpoint_ = endpointBuilder_.build();
          }
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          to_bitField0_ |= 0x00000004;
        }
        result.errorType_ = errorType_;
        if (((from_bitField0_ & 0x00000008) != 0)) {
          to_bitField0_ |= 0x00000008;
        }
        result.message_ = message_;
        if (((from_bitField0_ & 0x00000010) != 0)) {
          if (exceptionBuilder_ == null) {
            result.exception_ = exception_;
          } else {
            result.exception_ = exceptionBuilder_.build();
          }
          to_bitField0_ |= 0x00000010;
        }
        if (parsingErrorBuilder_ == null) {
          if (((bitField0_ & 0x00000020) != 0)) {
            parsingError_ = java.util.Collections.unmodifiableList(parsingError_);
            bitField0_ = (bitField0_ & ~0x00000020);
          }
          result.parsingError_ = parsingError_;
        } else {
          result.parsingError_ = parsingErrorBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserBitShared.DrillPBError) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.DrillPBError)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.DrillPBError other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance()) return this;
        if (other.hasErrorId()) {
          bitField0_ |= 0x00000001;
          errorId_ = other.errorId_;
          onChanged();
        }
        if (other.hasEndpoint()) {
          mergeEndpoint(other.getEndpoint());
        }
        if (other.hasErrorType()) {
          setErrorType(other.getErrorType());
        }
        if (other.hasMessage()) {
          bitField0_ |= 0x00000008;
          message_ = other.message_;
          onChanged();
        }
        if (other.hasException()) {
          mergeException(other.getException());
        }
        if (parsingErrorBuilder_ == null) {
          if (!other.parsingError_.isEmpty()) {
            if (parsingError_.isEmpty()) {
              parsingError_ = other.parsingError_;
              bitField0_ = (bitField0_ & ~0x00000020);
            } else {
              ensureParsingErrorIsMutable();
              parsingError_.addAll(other.parsingError_);
            }
            onChanged();
          }
        } else {
          if (!other.parsingError_.isEmpty()) {
            if (parsingErrorBuilder_.isEmpty()) {
              parsingErrorBuilder_.dispose();
              parsingErrorBuilder_ = null;
              parsingError_ = other.parsingError_;
              bitField0_ = (bitField0_ & ~0x00000020);
              parsingErrorBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getParsingErrorFieldBuilder() : null;
            } else {
              parsingErrorBuilder_.addAllMessages(other.parsingError_);
            }
          }
        }
        this.mergeUnknownFields(other.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>
       * @return Whether the errorId field is set.
       */
      public boolean hasErrorId() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <pre>
       * for debug tracing purposes
       * </pre>
       *
       * <code>optional string error_id = 1;</code>
       * @return The errorId.
       */
      public java.lang.String getErrorId() {
        java.lang.Object ref = errorId_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            errorId_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * for debug tracing purposes
       * </pre>
       *
       * <code>optional string error_id = 1;</code>
       * @return The bytes for errorId.
       */
      public com.google.protobuf.ByteString
          getErrorIdBytes() {
        java.lang.Object ref = errorId_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          errorId_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * for debug tracing purposes
       * </pre>
       *
       * <code>optional string error_id = 1;</code>
       * @param value The errorId to set.
       * @return This builder for chaining.
       */
      public Builder setErrorId(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        errorId_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * for debug tracing purposes
       * </pre>
       *
       * <code>optional string error_id = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearErrorId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        errorId_ = getDefaultInstance().getErrorId();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * for debug tracing purposes
       * </pre>
       *
       * <code>optional string error_id = 1;</code>
       * @param value The bytes for errorId to set.
       * @return This builder for chaining.
       */
      public Builder setErrorIdBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        errorId_ = value;
        onChanged();
        return this;
      }

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

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

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

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

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

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

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

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


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

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

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

    @java.lang.Deprecated public static final com.google.protobuf.Parser<DrillPBError>
        PARSER = new com.google.protobuf.AbstractParser<DrillPBError>() {
      @java.lang.Override
      public DrillPBError parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        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>
     * @return Whether the exceptionClass field is set.
     */
    boolean hasExceptionClass();
    /**
     * <code>optional string exception_class = 1;</code>
     * @return The exceptionClass.
     */
    java.lang.String getExceptionClass();
    /**
     * <code>optional string exception_class = 1;</code>
     * @return The bytes for exceptionClass.
     */
    com.google.protobuf.ByteString
        getExceptionClassBytes();

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

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

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

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

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

    public static final int MESSAGE_FIELD_NUMBER = 2;
    private volatile java.lang.Object message_;
    /**
     * <code>optional string message = 2;</code>
     * @return Whether the message field is set.
     */
    public boolean hasMessage() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional string message = 2;</code>
     * @return The message.
     */
    public java.lang.String getMessage() {
      java.lang.Object ref = message_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          message_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string message = 2;</code>
     * @return The bytes for message.
     */
    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>
     * @return Whether the cause field is set.
     */
    public boolean hasCause() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional .exec.shared.ExceptionWrapper cause = 4;</code>
     * @return The cause.
     */
    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) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, exceptionClass_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, message_);
      }
      for (int i = 0; i < stackTrace_.size(); i++) {
        output.writeMessage(3, stackTrace_.get(i));
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeMessage(4, getCause());
      }
      unknownFields.writeTo(output);
    }

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

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

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

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (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) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.exceptionClass_ = exceptionClass_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          to_bitField0_ |= 0x00000002;
        }
        result.message_ = message_;
        if (stackTraceBuilder_ == null) {
          if (((bitField0_ & 0x00000004) != 0)) {
            stackTrace_ = java.util.Collections.unmodifiableList(stackTrace_);
            bitField0_ = (bitField0_ & ~0x00000004);
          }
          result.stackTrace_ = stackTrace_;
        } else {
          result.stackTrace_ = stackTraceBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000008) != 0)) {
          if (causeBuilder_ == null) {
            result.cause_ = cause_;
          } else {
            result.cause_ = causeBuilder_.build();
          }
          to_bitField0_ |= 0x00000004;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.ExceptionWrapper.getDefaultInstance()) return this;
        if (other.hasExceptionClass()) {
          bitField0_ |= 0x00000001;
          exceptionClass_ = other.exceptionClass_;
          onChanged();
        }
        if (other.hasMessage()) {
          bitField0_ |= 0x00000002;
          message_ = other.message_;
          onChanged();
        }
        if (stackTraceBuilder_ == null) {
          if (!other.stackTrace_.isEmpty()) {
            if (stackTrace_.isEmpty()) {
              stackTrace_ = other.stackTrace_;
              bitField0_ = (bitField0_ & ~0x00000004);
            } else {
              ensureStackTraceIsMutable();
              stackTrace_.addAll(other.stackTrace_);
            }
            onChanged();
          }
        } else {
          if (!other.stackTrace_.isEmpty()) {
            if (stackTraceBuilder_.isEmpty()) {
              stackTraceBuilder_.dispose();
              stackTraceBuilder_ = null;
              stackTrace_ = other.stackTrace_;
              bitField0_ = (bitField0_ & ~0x00000004);
              stackTraceBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getStackTraceFieldBuilder() : null;
            } else {
              stackTraceBuilder_.addAllMessages(other.stackTrace_);
            }
          }
        }
        if (other.hasCause()) {
          mergeCause(other.getCause());
        }
        this.mergeUnknownFields(other.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>
       * @return Whether the exceptionClass field is set.
       */
      public boolean hasExceptionClass() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional string exception_class = 1;</code>
       * @return The exceptionClass.
       */
      public java.lang.String getExceptionClass() {
        java.lang.Object ref = exceptionClass_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            exceptionClass_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string exception_class = 1;</code>
       * @return The bytes for exceptionClass.
       */
      public com.google.protobuf.ByteString
          getExceptionClassBytes() {
        java.lang.Object ref = exceptionClass_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          exceptionClass_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string exception_class = 1;</code>
       * @param value The exceptionClass to set.
       * @return This builder for chaining.
       */
      public Builder setExceptionClass(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        exceptionClass_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception_class = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearExceptionClass() {
        bitField0_ = (bitField0_ & ~0x00000001);
        exceptionClass_ = getDefaultInstance().getExceptionClass();
        onChanged();
        return this;
      }
      /**
       * <code>optional string exception_class = 1;</code>
       * @param value The bytes for exceptionClass to set.
       * @return This builder for chaining.
       */
      public Builder setExceptionClassBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        exceptionClass_ = value;
        onChanged();
        return this;
      }

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

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

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

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

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

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


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

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

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

    @java.lang.Deprecated public static final com.google.protobuf.Parser<ExceptionWrapper>
        PARSER = new com.google.protobuf.AbstractParser<ExceptionWrapper>() {
      @java.lang.Override
      public ExceptionWrapper parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        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>
     * @return Whether the className field is set.
     */
    boolean hasClassName();
    /**
     * <code>optional string class_name = 1;</code>
     * @return The className.
     */
    java.lang.String getClassName();
    /**
     * <code>optional string class_name = 1;</code>
     * @return The bytes for className.
     */
    com.google.protobuf.ByteString
        getClassNameBytes();

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

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

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

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

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

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    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>
     * @return Whether the className field is set.
     */
    public boolean hasClassName() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional string class_name = 1;</code>
     * @return The className.
     */
    public java.lang.String getClassName() {
      java.lang.Object ref = className_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          className_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string class_name = 1;</code>
     * @return The bytes for className.
     */
    public com.google.protobuf.ByteString
        getClassNameBytes() {
      java.lang.Object ref = className_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        className_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

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

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

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

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

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

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, className_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, fileName_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeInt32(3, lineNumber_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 4, methodName_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        output.writeBool(5, isNativeMethod_);
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, className_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, fileName_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(3, lineNumber_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, methodName_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(5, isNativeMethod_);
      }
      size += 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;

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

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (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) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.className_ = className_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          to_bitField0_ |= 0x00000002;
        }
        result.fileName_ = fileName_;
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.lineNumber_ = lineNumber_;
          to_bitField0_ |= 0x00000004;
        }
        if (((from_bitField0_ & 0x00000008) != 0)) {
          to_bitField0_ |= 0x00000008;
        }
        result.methodName_ = methodName_;
        if (((from_bitField0_ & 0x00000010) != 0)) {
          result.isNativeMethod_ = isNativeMethod_;
          to_bitField0_ |= 0x00000010;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.StackTraceElementWrapper.getDefaultInstance()) return this;
        if (other.hasClassName()) {
          bitField0_ |= 0x00000001;
          className_ = other.className_;
          onChanged();
        }
        if (other.hasFileName()) {
          bitField0_ |= 0x00000002;
          fileName_ = other.fileName_;
          onChanged();
        }
        if (other.hasLineNumber()) {
          setLineNumber(other.getLineNumber());
        }
        if (other.hasMethodName()) {
          bitField0_ |= 0x00000008;
          methodName_ = other.methodName_;
          onChanged();
        }
        if (other.hasIsNativeMethod()) {
          setIsNativeMethod(other.getIsNativeMethod());
        }
        this.mergeUnknownFields(other.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>
       * @return Whether the className field is set.
       */
      public boolean hasClassName() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional string class_name = 1;</code>
       * @return The className.
       */
      public java.lang.String getClassName() {
        java.lang.Object ref = className_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            className_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string class_name = 1;</code>
       * @return The bytes for className.
       */
      public com.google.protobuf.ByteString
          getClassNameBytes() {
        java.lang.Object ref = className_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          className_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string class_name = 1;</code>
       * @param value The className to set.
       * @return This builder for chaining.
       */
      public Builder setClassName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        className_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string class_name = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearClassName() {
        bitField0_ = (bitField0_ & ~0x00000001);
        className_ = getDefaultInstance().getClassName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string class_name = 1;</code>
       * @param value The bytes for className to set.
       * @return This builder for chaining.
       */
      public Builder setClassNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        className_ = value;
        onChanged();
        return this;
      }

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

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

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

      private boolean isNativeMethod_ ;
      /**
       * <code>optional bool is_native_method = 5;</code>
       * @return Whether the isNativeMethod field is set.
       */
      public boolean hasIsNativeMethod() {
        return ((bitField0_ & 0x00000010) != 0);
      }
      /**
       * <code>optional bool is_native_method = 5;</code>
       * @return The isNativeMethod.
       */
      public boolean getIsNativeMethod() {
        return isNativeMethod_;
      }
      /**
       * <code>optional bool is_native_method = 5;</code>
       * @param value The isNativeMethod to set.
       * @return This builder for chaining.
       */
      public Builder setIsNativeMethod(boolean value) {
        bitField0_ |= 0x00000010;
        isNativeMethod_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool is_native_method = 5;</code>
       * @return This builder for chaining.
       */
      public Builder clearIsNativeMethod() {
        bitField0_ = (bitField0_ & ~0x00000010);
        isNativeMethod_ = false;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

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


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

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

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

    @java.lang.Deprecated public static final com.google.protobuf.Parser<StackTraceElementWrapper>
        PARSER = new com.google.protobuf.AbstractParser<StackTraceElementWrapper>() {
      @java.lang.Override
      public StackTraceElementWrapper parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        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>
     * @return Whether the startColumn field is set.
     */
    boolean hasStartColumn();
    /**
     * <code>optional int32 start_column = 2;</code>
     * @return The startColumn.
     */
    int getStartColumn();

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

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

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

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

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    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>
     * @return Whether the startColumn field is set.
     */
    public boolean hasStartColumn() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional int32 start_column = 2;</code>
     * @return The startColumn.
     */
    public int getStartColumn() {
      return startColumn_;
    }

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

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

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

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

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeInt32(2, startColumn_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeInt32(3, startRow_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeInt32(4, endColumn_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        output.writeInt32(5, endRow_);
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(2, startColumn_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(3, startRow_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(4, endColumn_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(5, endRow_);
      }
      size += 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;

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

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (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) != 0)) {
          result.startColumn_ = startColumn_;
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.startRow_ = startRow_;
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.endColumn_ = endColumn_;
          to_bitField0_ |= 0x00000004;
        }
        if (((from_bitField0_ & 0x00000008) != 0)) {
          result.endRow_ = endRow_;
          to_bitField0_ |= 0x00000008;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserBitShared.ParsingError) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.ParsingError)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.ParsingError other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.ParsingError.getDefaultInstance()) return this;
        if (other.hasStartColumn()) {
          setStartColumn(other.getStartColumn());
        }
        if (other.hasStartRow()) {
          setStartRow(other.getStartRow());
        }
        if (other.hasEndColumn()) {
          setEndColumn(other.getEndColumn());
        }
        if (other.hasEndRow()) {
          setEndRow(other.getEndRow());
        }
        this.mergeUnknownFields(other.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>
       * @return Whether the startColumn field is set.
       */
      public boolean hasStartColumn() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional int32 start_column = 2;</code>
       * @return The startColumn.
       */
      public int getStartColumn() {
        return startColumn_;
      }
      /**
       * <code>optional int32 start_column = 2;</code>
       * @param value The startColumn to set.
       * @return This builder for chaining.
       */
      public Builder setStartColumn(int value) {
        bitField0_ |= 0x00000001;
        startColumn_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 start_column = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearStartColumn() {
        bitField0_ = (bitField0_ & ~0x00000001);
        startColumn_ = 0;
        onChanged();
        return this;
      }

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

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

      private int endRow_ ;
      /**
       * <code>optional int32 end_row = 5;</code>
       * @return Whether the endRow field is set.
       */
      public boolean hasEndRow() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <code>optional int32 end_row = 5;</code>
       * @return The endRow.
       */
      public int getEndRow() {
        return endRow_;
      }
      /**
       * <code>optional int32 end_row = 5;</code>
       * @param value The endRow to set.
       * @return This builder for chaining.
       */
      public Builder setEndRow(int value) {
        bitField0_ |= 0x00000008;
        endRow_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 end_row = 5;</code>
       * @return This builder for chaining.
       */
      public Builder clearEndRow() {
        bitField0_ = (bitField0_ & ~0x00000008);
        endRow_ = 0;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

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


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

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

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

    @java.lang.Deprecated public static final com.google.protobuf.Parser<ParsingError>
        PARSER = new com.google.protobuf.AbstractParser<ParsingError>() {
      @java.lang.Override
      public ParsingError parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        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>
     * @return Whether the recordCount field is set.
     */
    boolean hasRecordCount();
    /**
     * <code>optional int32 record_count = 1;</code>
     * @return The recordCount.
     */
    int getRecordCount();

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

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

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

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

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    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) != 0)) {
                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) != 0)) {
          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>
     * @return Whether the recordCount field is set.
     */
    public boolean hasRecordCount() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional int32 record_count = 1;</code>
     * @return The recordCount.
     */
    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>
     * @return Whether the carriesTwoByteSelectionVector field is set.
     */
    public boolean hasCarriesTwoByteSelectionVector() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional bool carries_two_byte_selection_vector = 3;</code>
     * @return The carriesTwoByteSelectionVector.
     */
    public boolean getCarriesTwoByteSelectionVector() {
      return carriesTwoByteSelectionVector_;
    }

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

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

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeInt32(1, recordCount_);
      }
      for (int i = 0; i < field_.size(); i++) {
        output.writeMessage(2, field_.get(i));
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeBool(3, carriesTwoByteSelectionVector_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeInt32(4, affectedRowsCount_);
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(1, recordCount_);
      }
      for (int i = 0; i < field_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, field_.get(i));
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(3, carriesTwoByteSelectionVector_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(4, affectedRowsCount_);
      }
      size += 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;

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

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (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) != 0)) {
          result.recordCount_ = recordCount_;
          to_bitField0_ |= 0x00000001;
        }
        if (fieldBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0)) {
            field_ = java.util.Collections.unmodifiableList(field_);
            bitField0_ = (bitField0_ & ~0x00000002);
          }
          result.field_ = field_;
        } else {
          result.field_ = fieldBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.carriesTwoByteSelectionVector_ = carriesTwoByteSelectionVector_;
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000008) != 0)) {
          result.affectedRowsCount_ = affectedRowsCount_;
          to_bitField0_ |= 0x00000004;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserBitShared.RecordBatchDef) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.RecordBatchDef)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.RecordBatchDef other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.RecordBatchDef.getDefaultInstance()) return this;
        if (other.hasRecordCount()) {
          setRecordCount(other.getRecordCount());
        }
        if (fieldBuilder_ == null) {
          if (!other.field_.isEmpty()) {
            if (field_.isEmpty()) {
              field_ = other.field_;
              bitField0_ = (bitField0_ & ~0x00000002);
            } else {
              ensureFieldIsMutable();
              field_.addAll(other.field_);
            }
            onChanged();
          }
        } else {
          if (!other.field_.isEmpty()) {
            if (fieldBuilder_.isEmpty()) {
              fieldBuilder_.dispose();
              fieldBuilder_ = null;
              field_ = other.field_;
              bitField0_ = (bitField0_ & ~0x00000002);
              fieldBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getFieldFieldBuilder() : null;
            } else {
              fieldBuilder_.addAllMessages(other.field_);
            }
          }
        }
        if (other.hasCarriesTwoByteSelectionVector()) {
          setCarriesTwoByteSelectionVector(other.getCarriesTwoByteSelectionVector());
        }
        if (other.hasAffectedRowsCount()) {
          setAffectedRowsCount(other.getAffectedRowsCount());
        }
        this.mergeUnknownFields(other.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>
       * @return Whether the recordCount field is set.
       */
      public boolean hasRecordCount() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional int32 record_count = 1;</code>
       * @return The recordCount.
       */
      public int getRecordCount() {
        return recordCount_;
      }
      /**
       * <code>optional int32 record_count = 1;</code>
       * @param value The recordCount to set.
       * @return This builder for chaining.
       */
      public Builder setRecordCount(int value) {
        bitField0_ |= 0x00000001;
        recordCount_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 record_count = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearRecordCount() {
        bitField0_ = (bitField0_ & ~0x00000001);
        recordCount_ = 0;
        onChanged();
        return this;
      }

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

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

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

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

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

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


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

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

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

    @java.lang.Deprecated public static final com.google.protobuf.Parser<RecordBatchDef>
        PARSER = new com.google.protobuf.AbstractParser<RecordBatchDef>() {
      @java.lang.Override
      public RecordBatchDef parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        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>
     * @return Whether the type field is set.
     */
    boolean hasType();
    /**
     * <code>optional .exec.shared.NamePart.Type type = 1;</code>
     * @return The type.
     */
    org.apache.drill.exec.proto.UserBitShared.NamePart.Type getType();

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

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

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

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

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

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

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

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

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

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

      private final int value;

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

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

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

    public static final int NAME_FIELD_NUMBER = 2;
    private volatile java.lang.Object name_;
    /**
     * <code>optional string name = 2;</code>
     * @return Whether the name field is set.
     */
    public boolean hasName() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional string name = 2;</code>
     * @return The name.
     */
    public java.lang.String getName() {
      java.lang.Object ref = name_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          name_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string name = 2;</code>
     * @return The bytes for name.
     */
    public com.google.protobuf.ByteString
        getNameBytes() {
      java.lang.Object ref = name_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        name_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

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

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(1, type_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, name_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, getChild());
      }
      size += 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;

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

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (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) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.type_ = type_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          to_bitField0_ |= 0x00000002;
        }
        result.name_ = name_;
        if (((from_bitField0_ & 0x00000004) != 0)) {
          if (childBuilder_ == null) {
            result.child_ = child_;
          } else {
            result.child_ = childBuilder_.build();
          }
          to_bitField0_ |= 0x00000004;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserBitShared.NamePart) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.NamePart)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.NamePart other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.NamePart.getDefaultInstance()) return this;
        if (other.hasType()) {
          setType(other.getType());
        }
        if (other.hasName()) {
          bitField0_ |= 0x00000002;
          name_ = other.name_;
          onChanged();
        }
        if (other.hasChild()) {
          mergeChild(other.getChild());
        }
        this.mergeUnknownFields(other.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>
       * @return Whether the type field is set.
       */
      public boolean hasType() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .exec.shared.NamePart.Type type = 1;</code>
       * @return The type.
       */
      public org.apache.drill.exec.proto.UserBitShared.NamePart.Type getType() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserBitShared.NamePart.Type result = org.apache.drill.exec.proto.UserBitShared.NamePart.Type.valueOf(type_);
        return result == null ? org.apache.drill.exec.proto.UserBitShared.NamePart.Type.NAME : result;
      }
      /**
       * <code>optional .exec.shared.NamePart.Type type = 1;</code>
       * @param value The type to set.
       * @return This builder for chaining.
       */
      public Builder setType(org.apache.drill.exec.proto.UserBitShared.NamePart.Type value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000001;
        type_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .exec.shared.NamePart.Type type = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearType() {
        bitField0_ = (bitField0_ & ~0x00000001);
        type_ = 0;
        onChanged();
        return this;
      }

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

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

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


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

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

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

    @java.lang.Deprecated public static final com.google.protobuf.Parser<NamePart>
        PARSER = new com.google.protobuf.AbstractParser<NamePart>() {
      @java.lang.Override
      public NamePart parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        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>
     * @return Whether the majorType field is set.
     */
    boolean hasMajorType();
    /**
     * <pre>
     * the type associated with this field.
     * </pre>
     *
     * <code>optional .common.MajorType major_type = 1;</code>
     * @return The majorType.
     */
    org.apache.drill.common.types.TypeProtos.MajorType getMajorType();
    /**
     * <pre>
     * the type associated with this field.
     * </pre>
     *
     * <code>optional .common.MajorType major_type = 1;</code>
     */
    org.apache.drill.common.types.TypeProtos.MajorTypeOrBuilder getMajorTypeOrBuilder();

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

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

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

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

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

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

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    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) != 0)) {
                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) != 0)) {
                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) != 0)) {
                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) != 0)) {
          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>
     * @return Whether the majorType field is set.
     */
    public boolean hasMajorType() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <pre>
     * the type associated with this field.
     * </pre>
     *
     * <code>optional .common.MajorType major_type = 1;</code>
     * @return The majorType.
     */
    public org.apache.drill.common.types.TypeProtos.MajorType getMajorType() {
      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>
     * @return Whether the namePart field is set.
     */
    public boolean hasNamePart() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .exec.shared.NamePart name_part = 2;</code>
     * @return The namePart.
     */
    public org.apache.drill.exec.proto.UserBitShared.NamePart getNamePart() {
      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>
     * @return Whether the valueCount field is set.
     */
    public boolean hasValueCount() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional int32 value_count = 4;</code>
     * @return The valueCount.
     */
    public int getValueCount() {
      return valueCount_;
    }

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

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

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

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeMessage(1, getMajorType());
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeMessage(2, getNamePart());
      }
      for (int i = 0; i < child_.size(); i++) {
        output.writeMessage(3, child_.get(i));
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeInt32(4, valueCount_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        output.writeInt32(5, varByteLength_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        output.writeInt32(7, bufferLength_);
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, getMajorType());
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, getNamePart());
      }
      for (int i = 0; i < child_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, child_.get(i));
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(4, valueCount_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(5, varByteLength_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(7, bufferLength_);
      }
      size += 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;

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

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (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) != 0)) {
          if (majorTypeBuilder_ == null) {
            result.majorType_ = majorType_;
          } else {
            result.majorType_ = majorTypeBuilder_.build();
          }
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          if (namePartBuilder_ == null) {
            result.namePart_ = namePart_;
          } else {
            result.namePart_ = namePartBuilder_.build();
          }
          to_bitField0_ |= 0x00000002;
        }
        if (childBuilder_ == null) {
          if (((bitField0_ & 0x00000004) != 0)) {
            child_ = java.util.Collections.unmodifiableList(child_);
            bitField0_ = (bitField0_ & ~0x00000004);
          }
          result.child_ = child_;
        } else {
          result.child_ = childBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000008) != 0)) {
          result.valueCount_ = valueCount_;
          to_bitField0_ |= 0x00000004;
        }
        if (((from_bitField0_ & 0x00000010) != 0)) {
          result.varByteLength_ = varByteLength_;
          to_bitField0_ |= 0x00000008;
        }
        if (((from_bitField0_ & 0x00000020) != 0)) {
          result.bufferLength_ = bufferLength_;
          to_bitField0_ |= 0x00000010;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserBitShared.SerializedField) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.SerializedField)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.SerializedField other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.SerializedField.getDefaultInstance()) return this;
        if (other.hasMajorType()) {
          mergeMajorType(other.getMajorType());
        }
        if (other.hasNamePart()) {
          mergeNamePart(other.getNamePart());
        }
        if (childBuilder_ == null) {
          if (!other.child_.isEmpty()) {
            if (child_.isEmpty()) {
              child_ = other.child_;
              bitField0_ = (bitField0_ & ~0x00000004);
            } else {
              ensureChildIsMutable();
              child_.addAll(other.child_);
            }
            onChanged();
          }
        } else {
          if (!other.child_.isEmpty()) {
            if (childBuilder_.isEmpty()) {
              childBuilder_.dispose();
              childBuilder_ = null;
              child_ = other.child_;
              bitField0_ = (bitField0_ & ~0x00000004);
              childBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getChildFieldBuilder() : null;
            } else {
              childBuilder_.addAllMessages(other.child_);
            }
          }
        }
        if (other.hasValueCount()) {
          setValueCount(other.getValueCount());
        }
        if (other.hasVarByteLength()) {
          setVarByteLength(other.getVarByteLength());
        }
        if (other.hasBufferLength()) {
          setBufferLength(other.getBufferLength());
        }
        this.mergeUnknownFields(other.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_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.common.types.TypeProtos.MajorType, org.apache.drill.common.types.TypeProtos.MajorType.Builder, org.apache.drill.common.types.TypeProtos.MajorTypeOrBuilder> majorTypeBuilder_;
      /**
       * <pre>
       * the type associated with this field.
       * </pre>
       *
       * <code>optional .common.MajorType major_type = 1;</code>
       * @return Whether the majorType field is set.
       */
      public boolean hasMajorType() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <pre>
       * the type associated with this field.
       * </pre>
       *
       * <code>optional .common.MajorType major_type = 1;</code>
       * @return The majorType.
       */
      public org.apache.drill.common.types.TypeProtos.MajorType getMajorType() {
        if (majorTypeBuilder_ == null) {
          return majorType_ == null ? org.apache.drill.common.types.TypeProtos.MajorType.getDefaultInstance() : majorType_;
        } else {
          return majorTypeBuilder_.getMessage();
        }
      }
      /**
       * <pre>
       * the type associated with this field.
       * </pre>
       *
       * <code>optional .common.MajorType major_type = 1;</code>
       */
      public Builder setMajorType(org.apache.drill.common.types.TypeProtos.MajorType value) {
        if (majorTypeBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          majorType_ = value;
          onChanged();
        } else {
          majorTypeBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <pre>
       * the type associated with this field.
       * </pre>
       *
       * <code>optional .common.MajorType major_type = 1;</code>
       */
      public Builder setMajorType(
          org.apache.drill.common.types.TypeProtos.MajorType.Builder builderForValue) {
        if (majorTypeBuilder_ == null) {
          majorType_ = builderForValue.build();
          onChanged();
        } else {
          majorTypeBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <pre>
       * the type associated with this field.
       * </pre>
       *
       * <code>optional .common.MajorType major_type = 1;</code>
       */
      public Builder mergeMajorType(org.apache.drill.common.types.TypeProtos.MajorType value) {
        if (majorTypeBuilder_ == null) {
          if (((bitField0_ & 0x00000001) != 0) &&
              majorType_ != null &&
              majorType_ != org.apache.drill.common.types.TypeProtos.MajorType.getDefaultInstance()) {
            majorType_ =
              org.apache.drill.common.types.TypeProtos.MajorType.newBuilder(majorType_).mergeFrom(value).buildPartial();
          } else {
            majorType_ = value;
          }
          onChanged();
        } else {
          majorTypeBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <pre>
       * the type associated with this field.
       * </pre>
       *
       * <code>optional .common.MajorType major_type = 1;</code>
       */
      public Builder clearMajorType() {
        if (majorTypeBuilder_ == null) {
          majorType_ = null;
          onChanged();
        } else {
          majorTypeBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <pre>
       * the type associated with this field.
       * </pre>
       *
       * <code>optional .common.MajorType major_type = 1;</code>
       */
      public org.apache.drill.common.types.TypeProtos.MajorType.Builder getMajorTypeBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getMajorTypeFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * the type associated with this field.
       * </pre>
       *
       * <code>optional .common.MajorType major_type = 1;</code>
       */
      public org.apache.drill.common.types.TypeProtos.MajorTypeOrBuilder getMajorTypeOrBuilder() {
        if (majorTypeBuilder_ != null) {
          return majorTypeBuilder_.getMessageOrBuilder();
        } else {
          return majorType_ == null ?
              org.apache.drill.common.types.TypeProtos.MajorType.getDefaultInstance() : majorType_;
        }
      }
      /**
       * <pre>
       * the type associated with this field.
       * </pre>
       *
       * <code>optional .common.MajorType major_type = 1;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.common.types.TypeProtos.MajorType, org.apache.drill.common.types.TypeProtos.MajorType.Builder, org.apache.drill.common.types.TypeProtos.MajorTypeOrBuilder> 
          getMajorTypeFieldBuilder() {
        if (majorTypeBuilder_ == null) {
          majorTypeBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.common.types.TypeProtos.MajorType, org.apache.drill.common.types.TypeProtos.MajorType.Builder, org.apache.drill.common.types.TypeProtos.MajorTypeOrBuilder>(
                  getMajorType(),
                  getParentForChildren(),
                  isClean());
          majorType_ = null;
        }
        return majorTypeBuilder_;
      }

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

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

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

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

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

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

      private int bufferLength_ ;
      /**
       * <code>optional int32 buffer_length = 7;</code>
       * @return Whether the bufferLength field is set.
       */
      public boolean hasBufferLength() {
        return ((bitField0_ & 0x00000020) != 0);
      }
      /**
       * <code>optional int32 buffer_length = 7;</code>
       * @return The bufferLength.
       */
      public int getBufferLength() {
        return bufferLength_;
      }
      /**
       * <code>optional int32 buffer_length = 7;</code>
       * @param value The bufferLength to set.
       * @return This builder for chaining.
       */
      public Builder setBufferLength(int value) {
        bitField0_ |= 0x00000020;
        bufferLength_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 buffer_length = 7;</code>
       * @return This builder for chaining.
       */
      public Builder clearBufferLength() {
        bitField0_ = (bitField0_ & ~0x00000020);
        bufferLength_ = 0;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

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


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

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

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

    @java.lang.Deprecated public static final com.google.protobuf.Parser<SerializedField>
        PARSER = new com.google.protobuf.AbstractParser<SerializedField>() {
      @java.lang.Override
      public SerializedField parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        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>
     * @return Whether the nodeId field is set.
     */
    boolean hasNodeId();
    /**
     * <code>optional int32 node_id = 1;</code>
     * @return The nodeId.
     */
    int getNodeId();

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

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

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    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>
     * @return Whether the nodeId field is set.
     */
    public boolean hasNodeId() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional int32 node_id = 1;</code>
     * @return The nodeId.
     */
    public int getNodeId() {
      return nodeId_;
    }

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

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

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeInt32(1, nodeId_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeInt64(2, memoryFootprint_);
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(1, nodeId_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, memoryFootprint_);
      }
      size += 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;

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

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (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) != 0)) {
          result.nodeId_ = nodeId_;
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.memoryFootprint_ = memoryFootprint_;
          to_bitField0_ |= 0x00000002;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserBitShared.NodeStatus) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.NodeStatus)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.NodeStatus other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.NodeStatus.getDefaultInstance()) return this;
        if (other.hasNodeId()) {
          setNodeId(other.getNodeId());
        }
        if (other.hasMemoryFootprint()) {
          setMemoryFootprint(other.getMemoryFootprint());
        }
        this.mergeUnknownFields(other.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>
       * @return Whether the nodeId field is set.
       */
      public boolean hasNodeId() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional int32 node_id = 1;</code>
       * @return The nodeId.
       */
      public int getNodeId() {
        return nodeId_;
      }
      /**
       * <code>optional int32 node_id = 1;</code>
       * @param value The nodeId to set.
       * @return This builder for chaining.
       */
      public Builder setNodeId(int value) {
        bitField0_ |= 0x00000001;
        nodeId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 node_id = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearNodeId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        nodeId_ = 0;
        onChanged();
        return this;
      }

      private long memoryFootprint_ ;
      /**
       * <code>optional int64 memory_footprint = 2;</code>
       * @return Whether the memoryFootprint field is set.
       */
      public boolean hasMemoryFootprint() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional int64 memory_footprint = 2;</code>
       * @return The memoryFootprint.
       */
      public long getMemoryFootprint() {
        return memoryFootprint_;
      }
      /**
       * <code>optional int64 memory_footprint = 2;</code>
       * @param value The memoryFootprint to set.
       * @return This builder for chaining.
       */
      public Builder setMemoryFootprint(long value) {
        bitField0_ |= 0x00000002;
        memoryFootprint_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 memory_footprint = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearMemoryFootprint() {
        bitField0_ = (bitField0_ & ~0x00000002);
        memoryFootprint_ = 0L;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

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


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

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

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

    @java.lang.Deprecated public static final com.google.protobuf.Parser<NodeStatus>
        PARSER = new com.google.protobuf.AbstractParser<NodeStatus>() {
      @java.lang.Override
      public NodeStatus parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        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>
     * @return Whether the queryState field is set.
     */
    boolean hasQueryState();
    /**
     * <code>optional .exec.shared.QueryResult.QueryState query_state = 1;</code>
     * @return The queryState.
     */
    org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState getQueryState();

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

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

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

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

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

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

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

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

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

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

      private final int value;

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

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

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

    public static final int QUERY_ID_FIELD_NUMBER = 2;
    private org.apache.drill.exec.proto.UserBitShared.QueryId queryId_;
    /**
     * <code>optional .exec.shared.QueryId query_id = 2;</code>
     * @return Whether the queryId field is set.
     */
    public boolean hasQueryId() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .exec.shared.QueryId query_id = 2;</code>
     * @return The queryId.
     */
    public org.apache.drill.exec.proto.UserBitShared.QueryId getQueryId() {
      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) != 0)) {
        output.writeEnum(1, queryState_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeMessage(2, getQueryId());
      }
      for (int i = 0; i < error_.size(); i++) {
        output.writeMessage(3, error_.get(i));
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(1, queryState_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, getQueryId());
      }
      for (int i = 0; i < error_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, error_.get(i));
      }
      size += 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;

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

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (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) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.queryState_ = queryState_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          if (queryIdBuilder_ == null) {
            result.queryId_ = queryId_;
          } else {
            result.queryId_ = queryIdBuilder_.build();
          }
          to_bitField0_ |= 0x00000002;
        }
        if (errorBuilder_ == null) {
          if (((bitField0_ & 0x00000004) != 0)) {
            error_ = java.util.Collections.unmodifiableList(error_);
            bitField0_ = (bitField0_ & ~0x00000004);
          }
          result.error_ = error_;
        } else {
          result.error_ = errorBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserBitShared.QueryResult) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.QueryResult)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.QueryResult other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.QueryResult.getDefaultInstance()) return this;
        if (other.hasQueryState()) {
          setQueryState(other.getQueryState());
        }
        if (other.hasQueryId()) {
          mergeQueryId(other.getQueryId());
        }
        if (errorBuilder_ == null) {
          if (!other.error_.isEmpty()) {
            if (error_.isEmpty()) {
              error_ = other.error_;
              bitField0_ = (bitField0_ & ~0x00000004);
            } else {
              ensureErrorIsMutable();
              error_.addAll(other.error_);
            }
            onChanged();
          }
        } else {
          if (!other.error_.isEmpty()) {
            if (errorBuilder_.isEmpty()) {
              errorBuilder_.dispose();
              errorBuilder_ = null;
              error_ = other.error_;
              bitField0_ = (bitField0_ & ~0x00000004);
              errorBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getErrorFieldBuilder() : null;
            } else {
              errorBuilder_.addAllMessages(other.error_);
            }
          }
        }
        this.mergeUnknownFields(other.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>
       * @return Whether the queryState field is set.
       */
      public boolean hasQueryState() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .exec.shared.QueryResult.QueryState query_state = 1;</code>
       * @return The queryState.
       */
      public org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState getQueryState() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState result = org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.valueOf(queryState_);
        return result == null ? org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.STARTING : result;
      }
      /**
       * <code>optional .exec.shared.QueryResult.QueryState query_state = 1;</code>
       * @param value The queryState to set.
       * @return This builder for chaining.
       */
      public Builder setQueryState(org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000001;
        queryState_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryResult.QueryState query_state = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearQueryState() {
        bitField0_ = (bitField0_ & ~0x00000001);
        queryState_ = 0;
        onChanged();
        return this;
      }

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

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

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

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

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


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

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

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

    @java.lang.Deprecated public static final com.google.protobuf.Parser<QueryResult>
        PARSER = new com.google.protobuf.AbstractParser<QueryResult>() {
      @java.lang.Override
      public QueryResult parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        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>
     * @return Whether the queryId field is set.
     */
    boolean hasQueryId();
    /**
     * <code>optional .exec.shared.QueryId query_id = 1;</code>
     * @return The queryId.
     */
    org.apache.drill.exec.proto.UserBitShared.QueryId getQueryId();
    /**
     * <code>optional .exec.shared.QueryId query_id = 1;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder getQueryIdOrBuilder();

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

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

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

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

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    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) != 0)) {
                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) != 0)) {
                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>
     * @return Whether the queryId field is set.
     */
    public boolean hasQueryId() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional .exec.shared.QueryId query_id = 1;</code>
     * @return The queryId.
     */
    public org.apache.drill.exec.proto.UserBitShared.QueryId getQueryId() {
      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>
     * @return Whether the rowCount field is set.
     */
    public boolean hasRowCount() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional int32 row_count = 2;</code>
     * @return The rowCount.
     */
    public int getRowCount() {
      return rowCount_;
    }

    public static final int DEF_FIELD_NUMBER = 3;
    private org.apache.drill.exec.proto.UserBitShared.RecordBatchDef def_;
    /**
     * <code>optional .exec.shared.RecordBatchDef def = 3;</code>
     * @return Whether the def field is set.
     */
    public boolean hasDef() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional .exec.shared.RecordBatchDef def = 3;</code>
     * @return The def.
     */
    public org.apache.drill.exec.proto.UserBitShared.RecordBatchDef getDef() {
      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>
     * @return Whether the affectedRowsCount field is set.
     */
    public boolean hasAffectedRowsCount() {
      return ((bitField0_ & 0x00000008) != 0);
    }
    /**
     * <code>optional int32 affected_rows_count = 4;</code>
     * @return The affectedRowsCount.
     */
    public int getAffectedRowsCount() {
      return affectedRowsCount_;
    }

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

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeMessage(1, getQueryId());
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeInt32(2, rowCount_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeMessage(3, getDef());
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        output.writeInt32(4, affectedRowsCount_);
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, getQueryId());
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(2, rowCount_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, getDef());
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(4, affectedRowsCount_);
      }
      size += 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;

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

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (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) != 0)) {
          if (queryIdBuilder_ == null) {
            result.queryId_ = queryId_;
          } else {
            result.queryId_ = queryIdBuilder_.build();
          }
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.rowCount_ = rowCount_;
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          if (defBuilder_ == null) {
            result.def_ = def_;
          } else {
            result.def_ = defBuilder_.build();
          }
          to_bitField0_ |= 0x00000004;
        }
        if (((from_bitField0_ & 0x00000008) != 0)) {
          result.affectedRowsCount_ = affectedRowsCount_;
          to_bitField0_ |= 0x00000008;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserBitShared.QueryData) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.QueryData)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

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

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

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

      private int affectedRowsCount_ ;
      /**
       * <code>optional int32 affected_rows_count = 4;</code>
       * @return Whether the affectedRowsCount field is set.
       */
      public boolean hasAffectedRowsCount() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <code>optional int32 affected_rows_count = 4;</code>
       * @return The affectedRowsCount.
       */
      public int getAffectedRowsCount() {
        return affectedRowsCount_;
      }
      /**
       * <code>optional int32 affected_rows_count = 4;</code>
       * @param value The affectedRowsCount to set.
       * @return This builder for chaining.
       */
      public Builder setAffectedRowsCount(int value) {
        bitField0_ |= 0x00000008;
        affectedRowsCount_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 affected_rows_count = 4;</code>
       * @return This builder for chaining.
       */
      public Builder clearAffectedRowsCount() {
        bitField0_ = (bitField0_ & ~0x00000008);
        affectedRowsCount_ = 0;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

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


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

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

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

    @java.lang.Deprecated public static final com.google.protobuf.Parser<QueryData>
        PARSER = new com.google.protobuf.AbstractParser<QueryData>() {
      @java.lang.Override
      public QueryData parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        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>
     * @return Whether the query field is set.
     */
    boolean hasQuery();
    /**
     * <code>optional string query = 1;</code>
     * @return The query.
     */
    java.lang.String getQuery();
    /**
     * <code>optional string query = 1;</code>
     * @return The bytes for query.
     */
    com.google.protobuf.ByteString
        getQueryBytes();

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

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

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

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

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

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

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

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

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

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

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

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

    public static final int FOREMAN_FIELD_NUMBER = 5;
    private org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint foreman_;
    /**
     * <code>optional .exec.DrillbitEndpoint foreman = 5;</code>
     * @return Whether the foreman field is set.
     */
    public boolean hasForeman() {
      return ((bitField0_ & 0x00000010) != 0);
    }
    /**
     * <code>optional .exec.DrillbitEndpoint foreman = 5;</code>
     * @return The foreman.
     */
    public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint getForeman() {
      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>
     * @return Whether the optionsJson field is set.
     */
    public boolean hasOptionsJson() {
      return ((bitField0_ & 0x00000020) != 0);
    }
    /**
     * <code>optional string options_json = 6;</code>
     * @return The optionsJson.
     */
    public java.lang.String getOptionsJson() {
      java.lang.Object ref = optionsJson_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          optionsJson_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string options_json = 6;</code>
     * @return The bytes for optionsJson.
     */
    public com.google.protobuf.ByteString
        getOptionsJsonBytes() {
      java.lang.Object ref = optionsJson_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        optionsJson_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

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

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

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

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, query_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeInt64(2, start_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeEnum(3, state_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 4, user_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        output.writeMessage(5, getForeman());
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 6, optionsJson_);
      }
      if (((bitField0_ & 0x00000040) != 0)) {
        output.writeDouble(7, totalCost_);
      }
      if (((bitField0_ & 0x00000080) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 8, queueName_);
      }
      unknownFields.writeTo(output);
    }

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

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

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

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (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) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.query_ = query_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.start_ = start_;
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          to_bitField0_ |= 0x00000004;
        }
        result.state_ = state_;
        if (((from_bitField0_ & 0x00000008) != 0)) {
          to_bitField0_ |= 0x00000008;
        }
        result.user_ = user_;
        if (((from_bitField0_ & 0x00000010) != 0)) {
          if (foremanBuilder_ == null) {
            result.foreman_ = foreman_;
          } else {
            result.foreman_ = foremanBuilder_.build();
          }
          to_bitField0_ |= 0x00000010;
        }
        if (((from_bitField0_ & 0x00000020) != 0)) {
          to_bitField0_ |= 0x00000020;
        }
        result.optionsJson_ = optionsJson_;
        if (((from_bitField0_ & 0x00000040) != 0)) {
          result.totalCost_ = totalCost_;
          to_bitField0_ |= 0x00000040;
        }
        if (((from_bitField0_ & 0x00000080) != 0)) {
          to_bitField0_ |= 0x00000080;
        }
        result.queueName_ = queueName_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserBitShared.QueryInfo) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.QueryInfo)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.QueryInfo other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.QueryInfo.getDefaultInstance()) return this;
        if (other.hasQuery()) {
          bitField0_ |= 0x00000001;
          query_ = other.query_;
          onChanged();
        }
        if (other.hasStart()) {
          setStart(other.getStart());
        }
        if (other.hasState()) {
          setState(other.getState());
        }
        if (other.hasUser()) {
          bitField0_ |= 0x00000008;
          user_ = other.user_;
          onChanged();
        }
        if (other.hasForeman()) {
          mergeForeman(other.getForeman());
        }
        if (other.hasOptionsJson()) {
          bitField0_ |= 0x00000020;
          optionsJson_ = other.optionsJson_;
          onChanged();
        }
        if (other.hasTotalCost()) {
          setTotalCost(other.getTotalCost());
        }
        if (other.hasQueueName()) {
          bitField0_ |= 0x00000080;
          queueName_ = other.queueName_;
          onChanged();
        }
        this.mergeUnknownFields(other.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>
       * @return Whether the query field is set.
       */
      public boolean hasQuery() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional string query = 1;</code>
       * @return The query.
       */
      public java.lang.String getQuery() {
        java.lang.Object ref = query_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            query_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string query = 1;</code>
       * @return The bytes for query.
       */
      public com.google.protobuf.ByteString
          getQueryBytes() {
        java.lang.Object ref = query_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          query_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string query = 1;</code>
       * @param value The query to set.
       * @return This builder for chaining.
       */
      public Builder setQuery(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        query_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string query = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearQuery() {
        bitField0_ = (bitField0_ & ~0x00000001);
        query_ = getDefaultInstance().getQuery();
        onChanged();
        return this;
      }
      /**
       * <code>optional string query = 1;</code>
       * @param value The bytes for query to set.
       * @return This builder for chaining.
       */
      public Builder setQueryBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        query_ = value;
        onChanged();
        return this;
      }

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

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

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

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

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

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

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

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


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

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

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

    @java.lang.Deprecated public static final com.google.protobuf.Parser<QueryInfo>
        PARSER = new com.google.protobuf.AbstractParser<QueryInfo>() {
      @java.lang.Override
      public QueryInfo parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        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>
     * @return Whether the id field is set.
     */
    boolean hasId();
    /**
     * <code>optional .exec.shared.QueryId id = 1;</code>
     * @return The id.
     */
    org.apache.drill.exec.proto.UserBitShared.QueryId getId();
    /**
     * <code>optional .exec.shared.QueryId id = 1;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder getIdOrBuilder();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * <code>optional int32 autoLimit = 23;</code>
     * @return Whether the autoLimit field is set.
     */
    boolean hasAutoLimit();
    /**
     * <code>optional int32 autoLimit = 23;</code>
     * @return The autoLimit.
     */
    int getAutoLimit();
  }
  /**
   * Protobuf type {@code exec.shared.QueryProfile}
   */
  public  static final class QueryProfile extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.QueryProfile)
      QueryProfileOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use QueryProfile.newBuilder() to construct.
    private QueryProfile(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private QueryProfile() {
      type_ = 1;
      query_ = "";
      plan_ = "";
      state_ = 0;
      fragmentProfile_ = java.util.Collections.emptyList();
      user_ = "-";
      error_ = "";
      verboseError_ = "";
      errorId_ = "";
      errorNode_ = "";
      optionsJson_ = "";
      queueName_ = "-";
      queryId_ = "";
    }

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

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    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) != 0)) {
                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) != 0)) {
                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) != 0)) {
                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) != 0)) {
          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>
     * @return Whether the id field is set.
     */
    public boolean hasId() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional .exec.shared.QueryId id = 1;</code>
     * @return The id.
     */
    public org.apache.drill.exec.proto.UserBitShared.QueryId getId() {
      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>
     * @return Whether the type field is set.
     */
    public boolean hasType() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .exec.shared.QueryType type = 2;</code>
     * @return The type.
     */
    public org.apache.drill.exec.proto.UserBitShared.QueryType getType() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserBitShared.QueryType result = org.apache.drill.exec.proto.UserBitShared.QueryType.valueOf(type_);
      return result == null ? org.apache.drill.exec.proto.UserBitShared.QueryType.SQL : result;
    }

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

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

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

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

    public static final int FOREMAN_FIELD_NUMBER = 7;
    private org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint foreman_;
    /**
     * <code>optional .exec.DrillbitEndpoint foreman = 7;</code>
     * @return Whether the foreman field is set.
     */
    public boolean hasForeman() {
      return ((bitField0_ & 0x00000040) != 0);
    }
    /**
     * <code>optional .exec.DrillbitEndpoint foreman = 7;</code>
     * @return The foreman.
     */
    public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint getForeman() {
      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>
     * @return Whether the state field is set.
     */
    public boolean hasState() {
      return ((bitField0_ & 0x00000080) != 0);
    }
    /**
     * <code>optional .exec.shared.QueryResult.QueryState state = 8;</code>
     * @return The state.
     */
    public org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState getState() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState result = org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.valueOf(state_);
      return result == null ? org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.STARTING : result;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserBitShared.QueryProfile) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.QueryProfile)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.QueryProfile other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.QueryProfile.getDefaultInstance()) return this;
        if (other.hasId()) {
          mergeId(other.getId());
        }
        if (other.hasType()) {
          setType(other.getType());
        }
        if (other.hasStart()) {
          setStart(other.getStart());
        }
        if (other.hasEnd()) {
          setEnd(other.getEnd());
        }
        if (other.hasQuery()) {
          bitField0_ |= 0x00000010;
          query_ = other.query_;
          onChanged();
        }
        if (other.hasPlan()) {
          bitField0_ |= 0x00000020;
          plan_ = other.plan_;
          onChanged();
        }
        if (other.hasForeman()) {
          mergeForeman(other.getForeman());
        }
        if (other.hasState()) {
          setState(other.getState());
        }
        if (other.hasTotalFragments()) {
          setTotalFragments(other.getTotalFragments());
        }
        if (other.hasFinishedFragments()) {
          setFinishedFragments(other.getFinishedFragments());
        }
        if (fragmentProfileBuilder_ == null) {
          if (!other.fragmentProfile_.isEmpty()) {
            if (fragmentProfile_.isEmpty()) {
              fragmentProfile_ = other.fragmentProfile_;
              bitField0_ = (bitField0_ & ~0x00000400);
            } else {
              ensureFragmentProfileIsMutable();
              fragmentProfile_.addAll(other.fragmentProfile_);
            }
            onChanged();
          }
        } else {
          if (!other.fragmentProfile_.isEmpty()) {
            if (fragmentProfileBuilder_.isEmpty()) {
              fragmentProfileBuilder_.dispose();
              fragmentProfileBuilder_ = null;
              fragmentProfile_ = other.fragmentProfile_;
              bitField0_ = (bitField0_ & ~0x00000400);
              fragmentProfileBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getFragmentProfileFieldBuilder() : null;
            } else {
              fragmentProfileBuilder_.addAllMessages(other.fragmentProfile_);
            }
          }
        }
        if (other.hasUser()) {
          bitField0_ |= 0x00000800;
          user_ = other.user_;
          onChanged();
        }
        if (other.hasError()) {
          bitField0_ |= 0x00001000;
          error_ = other.error_;
          onChanged();
        }
        if (other.hasVerboseError()) {
          bitField0_ |= 0x00002000;
          verboseError_ = other.verboseError_;
          onChanged();
        }
        if (other.hasErrorId()) {
          bitField0_ |= 0x00004000;
          errorId_ = other.errorId_;
          onChanged();
        }
        if (other.hasErrorNode()) {
          bitField0_ |= 0x00008000;
          errorNode_ = other.errorNode_;
          onChanged();
        }
        if (other.hasOptionsJson()) {
          bitField0_ |= 0x00010000;
          optionsJson_ = other.optionsJson_;
          onChanged();
        }
        if (other.hasPlanEnd()) {
          setPlanEnd(other.getPlanEnd());
        }
        if (other.hasQueueWaitEnd()) {
          setQueueWaitEnd(other.getQueueWaitEnd());
        }
        if (other.hasTotalCost()) {
          setTotalCost(other.getTotalCost());
        }
        if (other.hasQueueName()) {
          bitField0_ |= 0x00100000;
          queueName_ = other.queueName_;
          onChanged();
        }
        if (other.hasQueryId()) {
          bitField0_ |= 0x00200000;
          queryId_ = other.queryId_;
          onChanged();
        }
        if (other.hasAutoLimit()) {
          setAutoLimit(other.getAutoLimit());
        }
        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_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.QueryId, org.apache.drill.exec.proto.UserBitShared.QueryId.Builder, org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder> idBuilder_;
      /**
       * <code>optional .exec.shared.QueryId id = 1;</code>
       * @return Whether the id field is set.
       */
      public boolean hasId() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .exec.shared.QueryId id = 1;</code>
       * @return The id.
       */
      public org.apache.drill.exec.proto.UserBitShared.QueryId getId() {
        if (idBuilder_ == null) {
          return id_ == null ? org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance() : id_;
        } else {
          return idBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.shared.QueryId id = 1;</code>
       */
      public Builder setId(org.apache.drill.exec.proto.UserBitShared.QueryId value) {
        if (idBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          id_ = value;
          onChanged();
        } else {
          idBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryId id = 1;</code>
       */
      public Builder setId(
          org.apache.drill.exec.proto.UserBitShared.QueryId.Builder builderForValue) {
        if (idBuilder_ == null) {
          id_ = builderForValue.build();
          onChanged();
        } else {
          idBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryId id = 1;</code>
       */
      public Builder mergeId(org.apache.drill.exec.proto.UserBitShared.QueryId value) {
        if (idBuilder_ == null) {
          if (((bitField0_ & 0x00000001) != 0) &&
              id_ != null &&
              id_ != org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance()) {
            id_ =
              org.apache.drill.exec.proto.UserBitShared.QueryId.newBuilder(id_).mergeFrom(value).buildPartial();
          } else {
            id_ = value;
          }
          onChanged();
        } else {
          idBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryId id = 1;</code>
       */
      public Builder clearId() {
        if (idBuilder_ == null) {
          id_ = null;
          onChanged();
        } else {
          idBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryId id = 1;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.QueryId.Builder getIdBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getIdFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.shared.QueryId id = 1;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder getIdOrBuilder() {
        if (idBuilder_ != null) {
          return idBuilder_.getMessageOrBuilder();
        } else {
          return id_ == null ?
              org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance() : id_;
        }
      }
      /**
       * <code>optional .exec.shared.QueryId id = 1;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.QueryId, org.apache.drill.exec.proto.UserBitShared.QueryId.Builder, org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder> 
          getIdFieldBuilder() {
        if (idBuilder_ == null) {
          idBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.QueryId, org.apache.drill.exec.proto.UserBitShared.QueryId.Builder, org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder>(
                  getId(),
                  getParentForChildren(),
                  isClean());
          id_ = null;
        }
        return idBuilder_;
      }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

      private int autoLimit_ ;
      /**
       * <code>optional int32 autoLimit = 23;</code>
       * @return Whether the autoLimit field is set.
       */
      public boolean hasAutoLimit() {
        return ((bitField0_ & 0x00400000) != 0);
      }
      /**
       * <code>optional int32 autoLimit = 23;</code>
       * @return The autoLimit.
       */
      public int getAutoLimit() {
        return autoLimit_;
      }
      /**
       * <code>optional int32 autoLimit = 23;</code>
       * @param value The autoLimit to set.
       * @return This builder for chaining.
       */
      public Builder setAutoLimit(int value) {
        bitField0_ |= 0x00400000;
        autoLimit_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 autoLimit = 23;</code>
       * @return This builder for chaining.
       */
      public Builder clearAutoLimit() {
        bitField0_ = (bitField0_ & ~0x00400000);
        autoLimit_ = 0;
        onChanged();
        return this;
      }
      @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>
     * @return Whether the majorFragmentId field is set.
     */
    boolean hasMajorFragmentId();
    /**
     * <code>optional int32 major_fragment_id = 1;</code>
     * @return The majorFragmentId.
     */
    int getMajorFragmentId();

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

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

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    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) != 0)) {
                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) != 0)) {
          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>
     * @return Whether the majorFragmentId field is set.
     */
    public boolean hasMajorFragmentId() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional int32 major_fragment_id = 1;</code>
     * @return The majorFragmentId.
     */
    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) != 0)) {
        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) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(1, majorFragmentId_);
      }
      for (int i = 0; i < minorFragmentProfile_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, minorFragmentProfile_.get(i));
      }
      size += 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;

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

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (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) != 0)) {
          result.majorFragmentId_ = majorFragmentId_;
          to_bitField0_ |= 0x00000001;
        }
        if (minorFragmentProfileBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0)) {
            minorFragmentProfile_ = java.util.Collections.unmodifiableList(minorFragmentProfile_);
            bitField0_ = (bitField0_ & ~0x00000002);
          }
          result.minorFragmentProfile_ = minorFragmentProfile_;
        } else {
          result.minorFragmentProfile_ = minorFragmentProfileBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile.getDefaultInstance()) return this;
        if (other.hasMajorFragmentId()) {
          setMajorFragmentId(other.getMajorFragmentId());
        }
        if (minorFragmentProfileBuilder_ == null) {
          if (!other.minorFragmentProfile_.isEmpty()) {
            if (minorFragmentProfile_.isEmpty()) {
              minorFragmentProfile_ = other.minorFragmentProfile_;
              bitField0_ = (bitField0_ & ~0x00000002);
            } else {
              ensureMinorFragmentProfileIsMutable();
              minorFragmentProfile_.addAll(other.minorFragmentProfile_);
            }
            onChanged();
          }
        } else {
          if (!other.minorFragmentProfile_.isEmpty()) {
            if (minorFragmentProfileBuilder_.isEmpty()) {
              minorFragmentProfileBuilder_.dispose();
              minorFragmentProfileBuilder_ = null;
              minorFragmentProfile_ = other.minorFragmentProfile_;
              bitField0_ = (bitField0_ & ~0x00000002);
              minorFragmentProfileBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getMinorFragmentProfileFieldBuilder() : null;
            } else {
              minorFragmentProfileBuilder_.addAllMessages(other.minorFragmentProfile_);
            }
          }
        }
        this.mergeUnknownFields(other.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>
       * @return Whether the majorFragmentId field is set.
       */
      public boolean hasMajorFragmentId() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional int32 major_fragment_id = 1;</code>
       * @return The majorFragmentId.
       */
      public int getMajorFragmentId() {
        return majorFragmentId_;
      }
      /**
       * <code>optional int32 major_fragment_id = 1;</code>
       * @param value The majorFragmentId to set.
       * @return This builder for chaining.
       */
      public Builder setMajorFragmentId(int value) {
        bitField0_ |= 0x00000001;
        majorFragmentId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 major_fragment_id = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearMajorFragmentId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        majorFragmentId_ = 0;
        onChanged();
        return this;
      }

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

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

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

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


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

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

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

    @java.lang.Deprecated public static final com.google.protobuf.Parser<MajorFragmentProfile>
        PARSER = new com.google.protobuf.AbstractParser<MajorFragmentProfile>() {
      @java.lang.Override
      public MajorFragmentProfile parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        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>
     * @return Whether the state field is set.
     */
    boolean hasState();
    /**
     * <code>optional .exec.shared.FragmentState state = 1;</code>
     * @return The state.
     */
    org.apache.drill.exec.proto.UserBitShared.FragmentState getState();

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

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

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

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

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

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

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

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

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

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

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

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    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) != 0)) {
                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) != 0)) {
                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) != 0)) {
                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) != 0)) {
          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>
     * @return Whether the state field is set.
     */
    public boolean hasState() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional .exec.shared.FragmentState state = 1;</code>
     * @return The state.
     */
    public org.apache.drill.exec.proto.UserBitShared.FragmentState getState() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserBitShared.FragmentState result = org.apache.drill.exec.proto.UserBitShared.FragmentState.valueOf(state_);
      return result == null ? org.apache.drill.exec.proto.UserBitShared.FragmentState.SENDING : result;
    }

    public static final int ERROR_FIELD_NUMBER = 2;
    private org.apache.drill.exec.proto.UserBitShared.DrillPBError error_;
    /**
     * <code>optional .exec.shared.DrillPBError error = 2;</code>
     * @return Whether the error field is set.
     */
    public boolean hasError() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .exec.shared.DrillPBError error = 2;</code>
     * @return The error.
     */
    public org.apache.drill.exec.proto.UserBitShared.DrillPBError getError() {
      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>
     * @return Whether the minorFragmentId field is set.
     */
    public boolean hasMinorFragmentId() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional int32 minor_fragment_id = 3;</code>
     * @return The minorFragmentId.
     */
    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>
     * @return Whether the startTime field is set.
     */
    public boolean hasStartTime() {
      return ((bitField0_ & 0x00000008) != 0);
    }
    /**
     * <code>optional int64 start_time = 5;</code>
     * @return The startTime.
     */
    public long getStartTime() {
      return startTime_;
    }

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

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

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

    public static final int ENDPOINT_FIELD_NUMBER = 9;
    private org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint endpoint_;
    /**
     * <code>optional .exec.DrillbitEndpoint endpoint = 9;</code>
     * @return Whether the endpoint field is set.
     */
    public boolean hasEndpoint() {
      return ((bitField0_ & 0x00000080) != 0);
    }
    /**
     * <code>optional .exec.DrillbitEndpoint endpoint = 9;</code>
     * @return The endpoint.
     */
    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>
     * @return Whether the lastUpdate field is set.
     */
    public boolean hasLastUpdate() {
      return ((bitField0_ & 0x00000100) != 0);
    }
    /**
     * <code>optional int64 last_update = 10;</code>
     * @return The lastUpdate.
     */
    public long getLastUpdate() {
      return lastUpdate_;
    }

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

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

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeEnum(1, state_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeMessage(2, getError());
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeInt32(3, minorFragmentId_);
      }
      for (int i = 0; i < operatorProfile_.size(); i++) {
        output.writeMessage(4, operatorProfile_.get(i));
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        output.writeInt64(5, startTime_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        output.writeInt64(6, endTime_);
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        output.writeInt64(7, memoryUsed_);
      }
      if (((bitField0_ & 0x00000040) != 0)) {
        output.writeInt64(8, maxMemoryUsed_);
      }
      if (((bitField0_ & 0x00000080) != 0)) {
        output.writeMessage(9, getEndpoint());
      }
      if (((bitField0_ & 0x00000100) != 0)) {
        output.writeInt64(10, lastUpdate_);
      }
      if (((bitField0_ & 0x00000200) != 0)) {
        output.writeInt64(11, lastProgress_);
      }
      unknownFields.writeTo(output);
    }

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

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

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

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

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.getDefaultInstance()) return this;
        if (other.hasState()) {
          setState(other.getState());
        }
        if (other.hasError()) {
          mergeError(other.getError());
        }
        if (other.hasMinorFragmentId()) {
          setMinorFragmentId(other.getMinorFragmentId());
        }
        if (operatorProfileBuilder_ == null) {
          if (!other.operatorProfile_.isEmpty()) {
            if (operatorProfile_.isEmpty()) {
              operatorProfile_ = other.operatorProfile_;
              bitField0_ = (bitField0_ & ~0x00000008);
            } else {
              ensureOperatorProfileIsMutable();
              operatorProfile_.addAll(other.operatorProfile_);
            }
            onChanged();
          }
        } else {
          if (!other.operatorProfile_.isEmpty()) {
            if (operatorProfileBuilder_.isEmpty()) {
              operatorProfileBuilder_.dispose();
              operatorProfileBuilder_ = null;
              operatorProfile_ = other.operatorProfile_;
              bitField0_ = (bitField0_ & ~0x00000008);
              operatorProfileBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getOperatorProfileFieldBuilder() : null;
            } else {
              operatorProfileBuilder_.addAllMessages(other.operatorProfile_);
            }
          }
        }
        if (other.hasStartTime()) {
          setStartTime(other.getStartTime());
        }
        if (other.hasEndTime()) {
          setEndTime(other.getEndTime());
        }
        if (other.hasMemoryUsed()) {
          setMemoryUsed(other.getMemoryUsed());
        }
        if (other.hasMaxMemoryUsed()) {
          setMaxMemoryUsed(other.getMaxMemoryUsed());
        }
        if (other.hasEndpoint()) {
          mergeEndpoint(other.getEndpoint());
        }
        if (other.hasLastUpdate()) {
          setLastUpdate(other.getLastUpdate());
        }
        if (other.hasLastProgress()) {
          setLastProgress(other.getLastProgress());
        }
        this.mergeUnknownFields(other.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>
       * @return Whether the state field is set.
       */
      public boolean hasState() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .exec.shared.FragmentState state = 1;</code>
       * @return The state.
       */
      public org.apache.drill.exec.proto.UserBitShared.FragmentState getState() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserBitShared.FragmentState result = org.apache.drill.exec.proto.UserBitShared.FragmentState.valueOf(state_);
        return result == null ? org.apache.drill.exec.proto.UserBitShared.FragmentState.SENDING : result;
      }
      /**
       * <code>optional .exec.shared.FragmentState state = 1;</code>
       * @param value The state to set.
       * @return This builder for chaining.
       */
      public Builder setState(org.apache.drill.exec.proto.UserBitShared.FragmentState value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000001;
        state_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .exec.shared.FragmentState state = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearState() {
        bitField0_ = (bitField0_ & ~0x00000001);
        state_ = 0;
        onChanged();
        return this;
      }

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

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

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

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

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

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

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

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

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

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

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

      private long lastProgress_ ;
      /**
       * <code>optional int64 last_progress = 11;</code>
       * @return Whether the lastProgress field is set.
       */
      public boolean hasLastProgress() {
        return ((bitField0_ & 0x00000400) != 0);
      }
      /**
       * <code>optional int64 last_progress = 11;</code>
       * @return The lastProgress.
       */
      public long getLastProgress() {
        return lastProgress_;
      }
      /**
       * <code>optional int64 last_progress = 11;</code>
       * @param value The lastProgress to set.
       * @return This builder for chaining.
       */
      public Builder setLastProgress(long value) {
        bitField0_ |= 0x00000400;
        lastProgress_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 last_progress = 11;</code>
       * @return This builder for chaining.
       */
      public Builder clearLastProgress() {
        bitField0_ = (bitField0_ & ~0x00000400);
        lastProgress_ = 0L;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

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


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

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

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

    @java.lang.Deprecated public static final com.google.protobuf.Parser<MinorFragmentProfile>
        PARSER = new com.google.protobuf.AbstractParser<MinorFragmentProfile>() {
      @java.lang.Override
      public MinorFragmentProfile parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        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>
     * @return Whether the operatorId field is set.
     */
    boolean hasOperatorId();
    /**
     * <code>optional int32 operator_id = 3;</code>
     * @return The operatorId.
     */
    int getOperatorId();

    /**
     * <code>optional int32 operator_type = 4;</code>
     * @return Whether the operatorType field is set.
     */
    boolean hasOperatorType();
    /**
     * <code>optional int32 operator_type = 4;</code>
     * @return The operatorType.
     */
    int getOperatorType();

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

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

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

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

    /**
     * <code>optional int64 wait_nanos = 9;</code>
     * @return Whether the waitNanos field is set.
     */
    boolean hasWaitNanos();
    /**
     * <code>optional int64 wait_nanos = 9;</code>
     * @return The waitNanos.
     */
    long getWaitNanos();
  }
  /**
   * Protobuf type {@code exec.shared.OperatorProfile}
   */
  public  static final class OperatorProfile extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.OperatorProfile)
      OperatorProfileOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use OperatorProfile.newBuilder() to construct.
    private OperatorProfile(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private OperatorProfile() {
      inputProfile_ = java.util.Collections.emptyList();
      metric_ = java.util.Collections.emptyList();
    }

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

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    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) != 0)) {
                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) != 0)) {
                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) != 0)) {
          inputProfile_ = java.util.Collections.unmodifiableList(inputProfile_);
        }
        if (((mutable_bitField0_ & 0x00000040) != 0)) {
          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>
     * @return Whether the operatorId field is set.
     */
    public boolean hasOperatorId() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional int32 operator_id = 3;</code>
     * @return The operatorId.
     */
    public int getOperatorId() {
      return operatorId_;
    }

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

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

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

    public static final int PEAK_LOCAL_MEMORY_ALLOCATED_FIELD_NUMBER = 7;
    private long peakLocalMemoryAllocated_;
    /**
     * <code>optional int64 peak_local_memory_allocated = 7;</code>
     * @return Whether the peakLocalMemoryAllocated field is set.
     */
    public boolean hasPeakLocalMemoryAllocated() {
      return ((bitField0_ & 0x00000010) != 0);
    }
    /**
     * <code>optional int64 peak_local_memory_allocated = 7;</code>
     * @return The peakLocalMemoryAllocated.
     */
    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>
     * @return Whether the waitNanos field is set.
     */
    public boolean hasWaitNanos() {
      return ((bitField0_ & 0x00000020) != 0);
    }
    /**
     * <code>optional int64 wait_nanos = 9;</code>
     * @return The waitNanos.
     */
    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) != 0)) {
        output.writeInt32(3, operatorId_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeInt32(4, operatorType_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeInt64(5, setupNanos_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        output.writeInt64(6, processNanos_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        output.writeInt64(7, peakLocalMemoryAllocated_);
      }
      for (int i = 0; i < metric_.size(); i++) {
        output.writeMessage(8, metric_.get(i));
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        output.writeInt64(9, waitNanos_);
      }
      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) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(3, operatorId_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(4, operatorType_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(5, setupNanos_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(6, processNanos_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(7, peakLocalMemoryAllocated_);
      }
      for (int i = 0; i < metric_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(8, metric_.get(i));
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(9, waitNanos_);
      }
      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;

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

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (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) != 0)) {
            inputProfile_ = java.util.Collections.unmodifiableList(inputProfile_);
            bitField0_ = (bitField0_ & ~0x00000001);
          }
          result.inputProfile_ = inputProfile_;
        } else {
          result.inputProfile_ = inputProfileBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.operatorId_ = operatorId_;
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.operatorType_ = operatorType_;
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000008) != 0)) {
          result.setupNanos_ = setupNanos_;
          to_bitField0_ |= 0x00000004;
        }
        if (((from_bitField0_ & 0x00000010) != 0)) {
          result.processNanos_ = processNanos_;
          to_bitField0_ |= 0x00000008;
        }
        if (((from_bitField0_ & 0x00000020) != 0)) {
          result.peakLocalMemoryAllocated_ = peakLocalMemoryAllocated_;
          to_bitField0_ |= 0x00000010;
        }
        if (metricBuilder_ == null) {
          if (((bitField0_ & 0x00000040) != 0)) {
            metric_ = java.util.Collections.unmodifiableList(metric_);
            bitField0_ = (bitField0_ & ~0x00000040);
          }
          result.metric_ = metric_;
        } else {
          result.metric_ = metricBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000080) != 0)) {
          result.waitNanos_ = waitNanos_;
          to_bitField0_ |= 0x00000020;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserBitShared.OperatorProfile) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.OperatorProfile)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.OperatorProfile other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.OperatorProfile.getDefaultInstance()) return this;
        if (inputProfileBuilder_ == null) {
          if (!other.inputProfile_.isEmpty()) {
            if (inputProfile_.isEmpty()) {
              inputProfile_ = other.inputProfile_;
              bitField0_ = (bitField0_ & ~0x00000001);
            } else {
              ensureInputProfileIsMutable();
              inputProfile_.addAll(other.inputProfile_);
            }
            onChanged();
          }
        } else {
          if (!other.inputProfile_.isEmpty()) {
            if (inputProfileBuilder_.isEmpty()) {
              inputProfileBuilder_.dispose();
              inputProfileBuilder_ = null;
              inputProfile_ = other.inputProfile_;
              bitField0_ = (bitField0_ & ~0x00000001);
              inputProfileBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getInputProfileFieldBuilder() : null;
            } else {
              inputProfileBuilder_.addAllMessages(other.inputProfile_);
            }
          }
        }
        if (other.hasOperatorId()) {
          setOperatorId(other.getOperatorId());
        }
        if (other.hasOperatorType()) {
          setOperatorType(other.getOperatorType());
        }
        if (other.hasSetupNanos()) {
          setSetupNanos(other.getSetupNanos());
        }
        if (other.hasProcessNanos()) {
          setProcessNanos(other.getProcessNanos());
        }
        if (other.hasPeakLocalMemoryAllocated()) {
          setPeakLocalMemoryAllocated(other.getPeakLocalMemoryAllocated());
        }
        if (metricBuilder_ == null) {
          if (!other.metric_.isEmpty()) {
            if (metric_.isEmpty()) {
              metric_ = other.metric_;
              bitField0_ = (bitField0_ & ~0x00000040);
            } else {
              ensureMetricIsMutable();
              metric_.addAll(other.metric_);
            }
            onChanged();
          }
        } else {
          if (!other.metric_.isEmpty()) {
            if (metricBuilder_.isEmpty()) {
              metricBuilder_.dispose();
              metricBuilder_ = null;
              metric_ = other.metric_;
              bitField0_ = (bitField0_ & ~0x00000040);
              metricBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getMetricFieldBuilder() : null;
            } else {
              metricBuilder_.addAllMessages(other.metric_);
            }
          }
        }
        if (other.hasWaitNanos()) {
          setWaitNanos(other.getWaitNanos());
        }
        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) != 0)) {
          inputProfile_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserBitShared.StreamProfile>(inputProfile_);
          bitField0_ |= 0x00000001;
         }
      }

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

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

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

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

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

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

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

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

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

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

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

    /**
     * <code>optional int64 batches = 2;</code>
     * @return Whether the batches field is set.
     */
    boolean hasBatches();
    /**
     * <code>optional int64 batches = 2;</code>
     * @return The batches.
     */
    long getBatches();

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

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

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    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>
     * @return Whether the records field is set.
     */
    public boolean hasRecords() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional int64 records = 1;</code>
     * @return The records.
     */
    public long getRecords() {
      return records_;
    }

    public static final int BATCHES_FIELD_NUMBER = 2;
    private long batches_;
    /**
     * <code>optional int64 batches = 2;</code>
     * @return Whether the batches field is set.
     */
    public boolean hasBatches() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional int64 batches = 2;</code>
     * @return The batches.
     */
    public long getBatches() {
      return batches_;
    }

    public static final int SCHEMAS_FIELD_NUMBER = 3;
    private long schemas_;
    /**
     * <code>optional int64 schemas = 3;</code>
     * @return Whether the schemas field is set.
     */
    public boolean hasSchemas() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional int64 schemas = 3;</code>
     * @return The schemas.
     */
    public long getSchemas() {
      return schemas_;
    }

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

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeInt64(1, records_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeInt64(2, batches_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeInt64(3, schemas_);
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(1, records_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, batches_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(3, schemas_);
      }
      size += 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;

      if (hasRecords() != other.hasRecords()) return false;
      if (hasRecords()) {
        if (getRecords()
            != other.getRecords()) return false;
      }
      if (hasBatches() != other.hasBatches()) return false;
      if (hasBatches()) {
        if (getBatches()
            != other.getBatches()) return false;
      }
      if (hasSchemas() != other.hasSchemas()) return false;
      if (hasSchemas()) {
        if (getSchemas()
            != other.getSchemas()) return false;
      }
      if (!unknownFields.equals(other.unknownFields)) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (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) != 0)) {
          result.records_ = records_;
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.batches_ = batches_;
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.schemas_ = schemas_;
          to_bitField0_ |= 0x00000004;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserBitShared.StreamProfile) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.StreamProfile)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.StreamProfile other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.StreamProfile.getDefaultInstance()) return this;
        if (other.hasRecords()) {
          setRecords(other.getRecords());
        }
        if (other.hasBatches()) {
          setBatches(other.getBatches());
        }
        if (other.hasSchemas()) {
          setSchemas(other.getSchemas());
        }
        this.mergeUnknownFields(other.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>
       * @return Whether the records field is set.
       */
      public boolean hasRecords() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional int64 records = 1;</code>
       * @return The records.
       */
      public long getRecords() {
        return records_;
      }
      /**
       * <code>optional int64 records = 1;</code>
       * @param value The records to set.
       * @return This builder for chaining.
       */
      public Builder setRecords(long value) {
        bitField0_ |= 0x00000001;
        records_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 records = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearRecords() {
        bitField0_ = (bitField0_ & ~0x00000001);
        records_ = 0L;
        onChanged();
        return this;
      }

      private long batches_ ;
      /**
       * <code>optional int64 batches = 2;</code>
       * @return Whether the batches field is set.
       */
      public boolean hasBatches() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional int64 batches = 2;</code>
       * @return The batches.
       */
      public long getBatches() {
        return batches_;
      }
      /**
       * <code>optional int64 batches = 2;</code>
       * @param value The batches to set.
       * @return This builder for chaining.
       */
      public Builder setBatches(long value) {
        bitField0_ |= 0x00000002;
        batches_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 batches = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearBatches() {
        bitField0_ = (bitField0_ & ~0x00000002);
        batches_ = 0L;
        onChanged();
        return this;
      }

      private long schemas_ ;
      /**
       * <code>optional int64 schemas = 3;</code>
       * @return Whether the schemas field is set.
       */
      public boolean hasSchemas() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional int64 schemas = 3;</code>
       * @return The schemas.
       */
      public long getSchemas() {
        return schemas_;
      }
      /**
       * <code>optional int64 schemas = 3;</code>
       * @param value The schemas to set.
       * @return This builder for chaining.
       */
      public Builder setSchemas(long value) {
        bitField0_ |= 0x00000004;
        schemas_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 schemas = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearSchemas() {
        bitField0_ = (bitField0_ & ~0x00000004);
        schemas_ = 0L;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

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


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

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

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

    @java.lang.Deprecated public static final com.google.protobuf.Parser<StreamProfile>
        PARSER = new com.google.protobuf.AbstractParser<StreamProfile>() {
      @java.lang.Override
      public StreamProfile parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        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>
     * @return Whether the metricId field is set.
     */
    boolean hasMetricId();
    /**
     * <code>optional int32 metric_id = 1;</code>
     * @return The metricId.
     */
    int getMetricId();

    /**
     * <code>optional int64 long_value = 2;</code>
     * @return Whether the longValue field is set.
     */
    boolean hasLongValue();
    /**
     * <code>optional int64 long_value = 2;</code>
     * @return The longValue.
     */
    long getLongValue();

    /**
     * <code>optional double double_value = 3;</code>
     * @return Whether the doubleValue field is set.
     */
    boolean hasDoubleValue();
    /**
     * <code>optional double double_value = 3;</code>
     * @return The doubleValue.
     */
    double getDoubleValue();
  }
  /**
   * Protobuf type {@code exec.shared.MetricValue}
   */
  public  static final class MetricValue extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.MetricValue)
      MetricValueOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use MetricValue.newBuilder() to construct.
    private MetricValue(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private MetricValue() {
    }

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

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    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>
     * @return Whether the metricId field is set.
     */
    public boolean hasMetricId() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional int32 metric_id = 1;</code>
     * @return The metricId.
     */
    public int getMetricId() {
      return metricId_;
    }

    public static final int LONG_VALUE_FIELD_NUMBER = 2;
    private long longValue_;
    /**
     * <code>optional int64 long_value = 2;</code>
     * @return Whether the longValue field is set.
     */
    public boolean hasLongValue() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional int64 long_value = 2;</code>
     * @return The longValue.
     */
    public long getLongValue() {
      return longValue_;
    }

    public static final int DOUBLE_VALUE_FIELD_NUMBER = 3;
    private double doubleValue_;
    /**
     * <code>optional double double_value = 3;</code>
     * @return Whether the doubleValue field is set.
     */
    public boolean hasDoubleValue() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional double double_value = 3;</code>
     * @return The doubleValue.
     */
    public double getDoubleValue() {
      return doubleValue_;
    }

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

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeInt32(1, metricId_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeInt64(2, longValue_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeDouble(3, doubleValue_);
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(1, metricId_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, longValue_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeDoubleSize(3, doubleValue_);
      }
      size += 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;

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

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (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) != 0)) {
          result.metricId_ = metricId_;
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.longValue_ = longValue_;
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.doubleValue_ = doubleValue_;
          to_bitField0_ |= 0x00000004;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserBitShared.MetricValue) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.MetricValue)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.MetricValue other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.MetricValue.getDefaultInstance()) return this;
        if (other.hasMetricId()) {
          setMetricId(other.getMetricId());
        }
        if (other.hasLongValue()) {
          setLongValue(other.getLongValue());
        }
        if (other.hasDoubleValue()) {
          setDoubleValue(other.getDoubleValue());
        }
        this.mergeUnknownFields(other.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>
       * @return Whether the metricId field is set.
       */
      public boolean hasMetricId() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional int32 metric_id = 1;</code>
       * @return The metricId.
       */
      public int getMetricId() {
        return metricId_;
      }
      /**
       * <code>optional int32 metric_id = 1;</code>
       * @param value The metricId to set.
       * @return This builder for chaining.
       */
      public Builder setMetricId(int value) {
        bitField0_ |= 0x00000001;
        metricId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 metric_id = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearMetricId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        metricId_ = 0;
        onChanged();
        return this;
      }

      private long longValue_ ;
      /**
       * <code>optional int64 long_value = 2;</code>
       * @return Whether the longValue field is set.
       */
      public boolean hasLongValue() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional int64 long_value = 2;</code>
       * @return The longValue.
       */
      public long getLongValue() {
        return longValue_;
      }
      /**
       * <code>optional int64 long_value = 2;</code>
       * @param value The longValue to set.
       * @return This builder for chaining.
       */
      public Builder setLongValue(long value) {
        bitField0_ |= 0x00000002;
        longValue_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 long_value = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearLongValue() {
        bitField0_ = (bitField0_ & ~0x00000002);
        longValue_ = 0L;
        onChanged();
        return this;
      }

      private double doubleValue_ ;
      /**
       * <code>optional double double_value = 3;</code>
       * @return Whether the doubleValue field is set.
       */
      public boolean hasDoubleValue() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional double double_value = 3;</code>
       * @return The doubleValue.
       */
      public double getDoubleValue() {
        return doubleValue_;
      }
      /**
       * <code>optional double double_value = 3;</code>
       * @param value The doubleValue to set.
       * @return This builder for chaining.
       */
      public Builder setDoubleValue(double value) {
        bitField0_ |= 0x00000004;
        doubleValue_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional double double_value = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearDoubleValue() {
        bitField0_ = (bitField0_ & ~0x00000004);
        doubleValue_ = 0D;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

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


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

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

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

    @java.lang.Deprecated public static final com.google.protobuf.Parser<MetricValue>
        PARSER = new com.google.protobuf.AbstractParser<MetricValue>() {
      @java.lang.Override
      public MetricValue parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        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
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new Registry();
    }

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

      if (!getJarList()
          .equals(other.getJarList())) return false;
      if (!unknownFields.equals(other.unknownFields)) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (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) != 0)) {
            jar_ = java.util.Collections.unmodifiableList(jar_);
            bitField0_ = (bitField0_ & ~0x00000001);
          }
          result.jar_ = jar_;
        } else {
          result.jar_ = jarBuilder_.build();
        }
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserBitShared.Registry) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.Registry)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.Registry other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.Registry.getDefaultInstance()) return this;
        if (jarBuilder_ == null) {
          if (!other.jar_.isEmpty()) {
            if (jar_.isEmpty()) {
              jar_ = other.jar_;
              bitField0_ = (bitField0_ & ~0x00000001);
            } else {
              ensureJarIsMutable();
              jar_.addAll(other.jar_);
            }
            onChanged();
          }
        } else {
          if (!other.jar_.isEmpty()) {
            if (jarBuilder_.isEmpty()) {
              jarBuilder_.dispose();
              jarBuilder_ = null;
              jar_ = other.jar_;
              bitField0_ = (bitField0_ & ~0x00000001);
              jarBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getJarFieldBuilder() : null;
            } else {
              jarBuilder_.addAllMessages(other.jar_);
            }
          }
        }
        this.mergeUnknownFields(other.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) != 0)) {
          jar_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserBitShared.Jar>(jar_);
          bitField0_ |= 0x00000001;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.Jar, org.apache.drill.exec.proto.UserBitShared.Jar.Builder, org.apache.drill.exec.proto.UserBitShared.JarOrBuilder> jarBuilder_;

      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserBitShared.Jar> getJarList() {
        if (jarBuilder_ == null) {
          return java.util.Collections.unmodifiableList(jar_);
        } else {
          return jarBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public int getJarCount() {
        if (jarBuilder_ == null) {
          return jar_.size();
        } else {
          return jarBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.Jar getJar(int index) {
        if (jarBuilder_ == null) {
          return jar_.get(index);
        } else {
          return jarBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public Builder setJar(
          int index, org.apache.drill.exec.proto.UserBitShared.Jar value) {
        if (jarBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureJarIsMutable();
          jar_.set(index, value);
          onChanged();
        } else {
          jarBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public Builder setJar(
          int index, org.apache.drill.exec.proto.UserBitShared.Jar.Builder builderForValue) {
        if (jarBuilder_ == null) {
          ensureJarIsMutable();
          jar_.set(index, builderForValue.build());
          onChanged();
        } else {
          jarBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public Builder addJar(org.apache.drill.exec.proto.UserBitShared.Jar value) {
        if (jarBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureJarIsMutable();
          jar_.add(value);
          onChanged();
        } else {
          jarBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public Builder addJar(
          int index, org.apache.drill.exec.proto.UserBitShared.Jar value) {
        if (jarBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureJarIsMutable();
          jar_.add(index, value);
          onChanged();
        } else {
          jarBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public Builder addJar(
          org.apache.drill.exec.proto.UserBitShared.Jar.Builder builderForValue) {
        if (jarBuilder_ == null) {
          ensureJarIsMutable();
          jar_.add(builderForValue.build());
          onChanged();
        } else {
          jarBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public Builder addJar(
          int index, org.apache.drill.exec.proto.UserBitShared.Jar.Builder builderForValue) {
        if (jarBuilder_ == null) {
          ensureJarIsMutable();
          jar_.add(index, builderForValue.build());
          onChanged();
        } else {
          jarBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public Builder addAllJar(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.UserBitShared.Jar> values) {
        if (jarBuilder_ == null) {
          ensureJarIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, jar_);
          onChanged();
        } else {
          jarBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public Builder clearJar() {
        if (jarBuilder_ == null) {
          jar_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
          onChanged();
        } else {
          jarBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public Builder removeJar(int index) {
        if (jarBuilder_ == null) {
          ensureJarIsMutable();
          jar_.remove(index);
          onChanged();
        } else {
          jarBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.Jar.Builder getJarBuilder(
          int index) {
        return getJarFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.JarOrBuilder getJarOrBuilder(
          int index) {
        if (jarBuilder_ == null) {
          return jar_.get(index);  } else {
          return jarBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public java.util.List<? extends org.apache.drill.exec.proto.UserBitShared.JarOrBuilder> 
           getJarOrBuilderList() {
        if (jarBuilder_ != null) {
          return jarBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(jar_);
        }
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.Jar.Builder addJarBuilder() {
        return getJarFieldBuilder().addBuilder(
            org.apache.drill.exec.proto.UserBitShared.Jar.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.Jar.Builder addJarBuilder(
          int index) {
        return getJarFieldBuilder().addBuilder(
            index, org.apache.drill.exec.proto.UserBitShared.Jar.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.shared.Jar jar = 1;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserBitShared.Jar.Builder> 
           getJarBuilderList() {
        return getJarFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.Jar, org.apache.drill.exec.proto.UserBitShared.Jar.Builder, org.apache.drill.exec.proto.UserBitShared.JarOrBuilder> 
          getJarFieldBuilder() {
        if (jarBuilder_ == null) {
          jarBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.Jar, org.apache.drill.exec.proto.UserBitShared.Jar.Builder, org.apache.drill.exec.proto.UserBitShared.JarOrBuilder>(
                  jar_,
                  ((bitField0_ & 0x00000001) != 0),
                  getParentForChildren(),
                  isClean());
          jar_ = null;
        }
        return jarBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

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


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

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

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

    @java.lang.Deprecated public static final com.google.protobuf.Parser<Registry>
        PARSER = new com.google.protobuf.AbstractParser<Registry>() {
      @java.lang.Override
      public Registry parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        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>
     * @return Whether the name field is set.
     */
    boolean hasName();
    /**
     * <code>optional string name = 1;</code>
     * @return The name.
     */
    java.lang.String getName();
    /**
     * <code>optional string name = 1;</code>
     * @return The bytes for name.
     */
    com.google.protobuf.ByteString
        getNameBytes();

    /**
     * <code>repeated string function_signature = 2;</code>
     * @return A list containing the functionSignature.
     */
    java.util.List<java.lang.String>
        getFunctionSignatureList();
    /**
     * <code>repeated string function_signature = 2;</code>
     * @return The count of functionSignature.
     */
    int getFunctionSignatureCount();
    /**
     * <code>repeated string function_signature = 2;</code>
     * @param index The index of the element to return.
     * @return The functionSignature at the given index.
     */
    java.lang.String getFunctionSignature(int index);
    /**
     * <code>repeated string function_signature = 2;</code>
     * @param index The index of the value to return.
     * @return The bytes of the functionSignature at the given index.
     */
    com.google.protobuf.ByteString
        getFunctionSignatureBytes(int index);
  }
  /**
   * <pre>
   * Jar contains jar name and list of function signatures.
   *Function signature is concatenation of function name and its input parameters. 
   * </pre>
   *
   * Protobuf type {@code exec.shared.Jar}
   */
  public  static final class Jar extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.Jar)
      JarOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use Jar.newBuilder() to construct.
    private Jar(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private Jar() {
      name_ = "";
      functionSignature_ = com.google.protobuf.LazyStringArrayList.EMPTY;
    }

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

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    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) != 0)) {
                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) != 0)) {
          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>
     * @return Whether the name field is set.
     */
    public boolean hasName() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional string name = 1;</code>
     * @return The name.
     */
    public java.lang.String getName() {
      java.lang.Object ref = name_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          name_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string name = 1;</code>
     * @return The bytes for name.
     */
    public com.google.protobuf.ByteString
        getNameBytes() {
      java.lang.Object ref = name_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        name_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int FUNCTION_SIGNATURE_FIELD_NUMBER = 2;
    private com.google.protobuf.LazyStringList functionSignature_;
    /**
     * <code>repeated string function_signature = 2;</code>
     * @return A list containing the functionSignature.
     */
    public com.google.protobuf.ProtocolStringList
        getFunctionSignatureList() {
      return functionSignature_;
    }
    /**
     * <code>repeated string function_signature = 2;</code>
     * @return The count of functionSignature.
     */
    public int getFunctionSignatureCount() {
      return functionSignature_.size();
    }
    /**
     * <code>repeated string function_signature = 2;</code>
     * @param index The index of the element to return.
     * @return The functionSignature at the given index.
     */
    public java.lang.String getFunctionSignature(int index) {
      return functionSignature_.get(index);
    }
    /**
     * <code>repeated string function_signature = 2;</code>
     * @param index The index of the value to return.
     * @return The bytes of the functionSignature at the given index.
     */
    public com.google.protobuf.ByteString
        getFunctionSignatureBytes(int index) {
      return functionSignature_.getByteString(index);
    }

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

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, name_);
      }
      for (int i = 0; i < functionSignature_.size(); i++) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, functionSignature_.getRaw(i));
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, name_);
      }
      {
        int dataSize = 0;
        for (int i = 0; i < functionSignature_.size(); i++) {
          dataSize += computeStringSizeNoTag(functionSignature_.getRaw(i));
        }
        size += dataSize;
        size += 1 * getFunctionSignatureList().size();
      }
      size += 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;

      if (hasName() != other.hasName()) return false;
      if (hasName()) {
        if (!getName()
            .equals(other.getName())) return false;
      }
      if (!getFunctionSignatureList()
          .equals(other.getFunctionSignatureList())) return false;
      if (!unknownFields.equals(other.unknownFields)) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (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) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.name_ = name_;
        if (((bitField0_ & 0x00000002) != 0)) {
          functionSignature_ = functionSignature_.getUnmodifiableView();
          bitField0_ = (bitField0_ & ~0x00000002);
        }
        result.functionSignature_ = functionSignature_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserBitShared.Jar) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.Jar)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.Jar other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.Jar.getDefaultInstance()) return this;
        if (other.hasName()) {
          bitField0_ |= 0x00000001;
          name_ = other.name_;
          onChanged();
        }
        if (!other.functionSignature_.isEmpty()) {
          if (functionSignature_.isEmpty()) {
            functionSignature_ = other.functionSignature_;
            bitField0_ = (bitField0_ & ~0x00000002);
          } else {
            ensureFunctionSignatureIsMutable();
            functionSignature_.addAll(other.functionSignature_);
          }
          onChanged();
        }
        this.mergeUnknownFields(other.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>
       * @return Whether the name field is set.
       */
      public boolean hasName() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional string name = 1;</code>
       * @return The name.
       */
      public java.lang.String getName() {
        java.lang.Object ref = name_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            name_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string name = 1;</code>
       * @return The bytes for name.
       */
      public com.google.protobuf.ByteString
          getNameBytes() {
        java.lang.Object ref = name_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          name_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string name = 1;</code>
       * @param value The name to set.
       * @return This builder for chaining.
       */
      public Builder setName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        name_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string name = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearName() {
        bitField0_ = (bitField0_ & ~0x00000001);
        name_ = getDefaultInstance().getName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string name = 1;</code>
       * @param value The bytes for name to set.
       * @return This builder for chaining.
       */
      public Builder setNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        name_ = value;
        onChanged();
        return this;
      }

      private com.google.protobuf.LazyStringList functionSignature_ = com.google.protobuf.LazyStringArrayList.EMPTY;
      private void ensureFunctionSignatureIsMutable() {
        if (!((bitField0_ & 0x00000002) != 0)) {
          functionSignature_ = new com.google.protobuf.LazyStringArrayList(functionSignature_);
          bitField0_ |= 0x00000002;
         }
      }
      /**
       * <code>repeated string function_signature = 2;</code>
       * @return A list containing the functionSignature.
       */
      public com.google.protobuf.ProtocolStringList
          getFunctionSignatureList() {
        return functionSignature_.getUnmodifiableView();
      }
      /**
       * <code>repeated string function_signature = 2;</code>
       * @return The count of functionSignature.
       */
      public int getFunctionSignatureCount() {
        return functionSignature_.size();
      }
      /**
       * <code>repeated string function_signature = 2;</code>
       * @param index The index of the element to return.
       * @return The functionSignature at the given index.
       */
      public java.lang.String getFunctionSignature(int index) {
        return functionSignature_.get(index);
      }
      /**
       * <code>repeated string function_signature = 2;</code>
       * @param index The index of the value to return.
       * @return The bytes of the functionSignature at the given index.
       */
      public com.google.protobuf.ByteString
          getFunctionSignatureBytes(int index) {
        return functionSignature_.getByteString(index);
      }
      /**
       * <code>repeated string function_signature = 2;</code>
       * @param index The index to set the value at.
       * @param value The functionSignature to set.
       * @return This builder for chaining.
       */
      public Builder setFunctionSignature(
          int index, java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureFunctionSignatureIsMutable();
        functionSignature_.set(index, value);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string function_signature = 2;</code>
       * @param value The functionSignature to add.
       * @return This builder for chaining.
       */
      public Builder addFunctionSignature(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureFunctionSignatureIsMutable();
        functionSignature_.add(value);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string function_signature = 2;</code>
       * @param values The functionSignature to add.
       * @return This builder for chaining.
       */
      public Builder addAllFunctionSignature(
          java.lang.Iterable<java.lang.String> values) {
        ensureFunctionSignatureIsMutable();
        com.google.protobuf.AbstractMessageLite.Builder.addAll(
            values, functionSignature_);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string function_signature = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearFunctionSignature() {
        functionSignature_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000002);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string function_signature = 2;</code>
       * @param value The bytes of the functionSignature to add.
       * @return This builder for chaining.
       */
      public Builder addFunctionSignatureBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureFunctionSignatureIsMutable();
        functionSignature_.add(value);
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

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


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

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

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

    @java.lang.Deprecated public static final com.google.protobuf.Parser<Jar>
        PARSER = new com.google.protobuf.AbstractParser<Jar>() {
      @java.lang.Override
      public Jar parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        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>
     * @return Whether the mechanism field is set.
     */
    boolean hasMechanism();
    /**
     * <code>optional string mechanism = 1;</code>
     * @return The mechanism.
     */
    java.lang.String getMechanism();
    /**
     * <code>optional string mechanism = 1;</code>
     * @return The bytes for mechanism.
     */
    com.google.protobuf.ByteString
        getMechanismBytes();

    /**
     * <code>optional bytes data = 2;</code>
     * @return Whether the data field is set.
     */
    boolean hasData();
    /**
     * <code>optional bytes data = 2;</code>
     * @return The data.
     */
    com.google.protobuf.ByteString getData();

    /**
     * <code>optional .exec.shared.SaslStatus status = 3;</code>
     * @return Whether the status field is set.
     */
    boolean hasStatus();
    /**
     * <code>optional .exec.shared.SaslStatus status = 3;</code>
     * @return The status.
     */
    org.apache.drill.exec.proto.UserBitShared.SaslStatus getStatus();
  }
  /**
   * Protobuf type {@code exec.shared.SaslMessage}
   */
  public  static final class SaslMessage extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.shared.SaslMessage)
      SaslMessageOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use SaslMessage.newBuilder() to construct.
    private SaslMessage(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private SaslMessage() {
      mechanism_ = "";
      data_ = com.google.protobuf.ByteString.EMPTY;
      status_ = 0;
    }

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

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    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>
     * @return Whether the mechanism field is set.
     */
    public boolean hasMechanism() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional string mechanism = 1;</code>
     * @return The mechanism.
     */
    public java.lang.String getMechanism() {
      java.lang.Object ref = mechanism_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          mechanism_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string mechanism = 1;</code>
     * @return The bytes for mechanism.
     */
    public com.google.protobuf.ByteString
        getMechanismBytes() {
      java.lang.Object ref = mechanism_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        mechanism_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int DATA_FIELD_NUMBER = 2;
    private com.google.protobuf.ByteString data_;
    /**
     * <code>optional bytes data = 2;</code>
     * @return Whether the data field is set.
     */
    public boolean hasData() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional bytes data = 2;</code>
     * @return The data.
     */
    public com.google.protobuf.ByteString getData() {
      return data_;
    }

    public static final int STATUS_FIELD_NUMBER = 3;
    private int status_;
    /**
     * <code>optional .exec.shared.SaslStatus status = 3;</code>
     * @return Whether the status field is set.
     */
    public boolean hasStatus() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional .exec.shared.SaslStatus status = 3;</code>
     * @return The status.
     */
    public org.apache.drill.exec.proto.UserBitShared.SaslStatus getStatus() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserBitShared.SaslStatus result = org.apache.drill.exec.proto.UserBitShared.SaslStatus.valueOf(status_);
      return result == null ? org.apache.drill.exec.proto.UserBitShared.SaslStatus.SASL_UNKNOWN : result;
    }

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

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, mechanism_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeBytes(2, data_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeEnum(3, status_);
      }
      unknownFields.writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, mechanism_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(2, data_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(3, status_);
      }
      size += 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;

      if (hasMechanism() != other.hasMechanism()) return false;
      if (hasMechanism()) {
        if (!getMechanism()
            .equals(other.getMechanism())) return false;
      }
      if (hasData() != other.hasData()) return false;
      if (hasData()) {
        if (!getData()
            .equals(other.getData())) return false;
      }
      if (hasStatus() != other.hasStatus()) return false;
      if (hasStatus()) {
        if (status_ != other.status_) return false;
      }
      if (!unknownFields.equals(other.unknownFields)) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (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) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.mechanism_ = mechanism_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          to_bitField0_ |= 0x00000002;
        }
        result.data_ = data_;
        if (((from_bitField0_ & 0x00000004) != 0)) {
          to_bitField0_ |= 0x00000004;
        }
        result.status_ = status_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserBitShared.SaslMessage) {
          return mergeFrom((org.apache.drill.exec.proto.UserBitShared.SaslMessage)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserBitShared.SaslMessage other) {
        if (other == org.apache.drill.exec.proto.UserBitShared.SaslMessage.getDefaultInstance()) return this;
        if (other.hasMechanism()) {
          bitField0_ |= 0x00000001;
          mechanism_ = other.mechanism_;
          onChanged();
        }
        if (other.hasData()) {
          setData(other.getData());
        }
        if (other.hasStatus()) {
          setStatus(other.getStatus());
        }
        this.mergeUnknownFields(other.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>
       * @return Whether the mechanism field is set.
       */
      public boolean hasMechanism() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional string mechanism = 1;</code>
       * @return The mechanism.
       */
      public java.lang.String getMechanism() {
        java.lang.Object ref = mechanism_;
        if (!(ref instanceof java.lang.String)) {
          com.google.protobuf.ByteString bs =
              (com.google.protobuf.ByteString) ref;
          java.lang.String s = bs.toStringUtf8();
          if (bs.isValidUtf8()) {
            mechanism_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string mechanism = 1;</code>
       * @return The bytes for mechanism.
       */
      public com.google.protobuf.ByteString
          getMechanismBytes() {
        java.lang.Object ref = mechanism_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          mechanism_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string mechanism = 1;</code>
       * @param value The mechanism to set.
       * @return This builder for chaining.
       */
      public Builder setMechanism(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        mechanism_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string mechanism = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearMechanism() {
        bitField0_ = (bitField0_ & ~0x00000001);
        mechanism_ = getDefaultInstance().getMechanism();
        onChanged();
        return this;
      }
      /**
       * <code>optional string mechanism = 1;</code>
       * @param value The bytes for mechanism to set.
       * @return This builder for chaining.
       */
      public Builder setMechanismBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        mechanism_ = value;
        onChanged();
        return this;
      }

      private com.google.protobuf.ByteString data_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>optional bytes data = 2;</code>
       * @return Whether the data field is set.
       */
      public boolean hasData() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional bytes data = 2;</code>
       * @return The data.
       */
      public com.google.protobuf.ByteString getData() {
        return data_;
      }
      /**
       * <code>optional bytes data = 2;</code>
       * @param value The data to set.
       * @return This builder for chaining.
       */
      public Builder setData(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        data_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bytes data = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearData() {
        bitField0_ = (bitField0_ & ~0x00000002);
        data_ = getDefaultInstance().getData();
        onChanged();
        return this;
      }

      private int status_ = 0;
      /**
       * <code>optional .exec.shared.SaslStatus status = 3;</code>
       * @return Whether the status field is set.
       */
      public boolean hasStatus() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional .exec.shared.SaslStatus status = 3;</code>
       * @return The status.
       */
      public org.apache.drill.exec.proto.UserBitShared.SaslStatus getStatus() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserBitShared.SaslStatus result = org.apache.drill.exec.proto.UserBitShared.SaslStatus.valueOf(status_);
        return result == null ? org.apache.drill.exec.proto.UserBitShared.SaslStatus.SASL_UNKNOWN : result;
      }
      /**
       * <code>optional .exec.shared.SaslStatus status = 3;</code>
       * @param value The status to set.
       * @return This builder for chaining.
       */
      public Builder setStatus(org.apache.drill.exec.proto.UserBitShared.SaslStatus value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000004;
        status_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .exec.shared.SaslStatus status = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearStatus() {
        bitField0_ = (bitField0_ & ~0x00000004);
        status_ = 0;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

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


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

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

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

    @java.lang.Deprecated public static final com.google.protobuf.Parser<SaslMessage>
        PARSER = new com.google.protobuf.AbstractParser<SaslMessage>() {
      @java.lang.Override
      public SaslMessage parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        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*\236\013\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\022\022\n\016DRUID_SUB_SCAN\020D\022\021\n\rSPSS_S" +
      "UB_SCAN\020E\022\021\n\rHTTP_SUB_SCAN\020F*g\n\nSaslStat" +
      "us\022\020\n\014SASL_UNKNOWN\020\000\022\016\n\nSASL_START\020\001\022\024\n\020" +
      "SASL_IN_PROGRESS\020\002\022\020\n\014SASL_SUCCESS\020\003\022\017\n\013" +
      "SASL_FAILED\020\004B.\n\033org.apache.drill.exec.p" +
      "rotoB\rUserBitSharedH\001"
    };
    descriptor = com.google.protobuf.Descriptors.FileDescriptor
      .internalBuildGeneratedFileFrom(descriptorData,
        new com.google.protobuf.Descriptors.FileDescriptor[] {
          org.apache.drill.common.types.TypeProtos.getDescriptor(),
          org.apache.drill.exec.proto.CoordinationProtos.getDescriptor(),
          org.apache.drill.exec.proto.SchemaDefProtos.getDescriptor(),
        });
    internal_static_exec_shared_UserCredentials_descriptor =
      getDescriptor().getMessageTypes().get(0);
    internal_static_exec_shared_UserCredentials_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_UserCredentials_descriptor,
        new java.lang.String[] { "UserName", });
    internal_static_exec_shared_QueryId_descriptor =
      getDescriptor().getMessageTypes().get(1);
    internal_static_exec_shared_QueryId_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_QueryId_descriptor,
        new java.lang.String[] { "Part1", "Part2", });
    internal_static_exec_shared_DrillPBError_descriptor =
      getDescriptor().getMessageTypes().get(2);
    internal_static_exec_shared_DrillPBError_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_DrillPBError_descriptor,
        new java.lang.String[] { "ErrorId", "Endpoint", "ErrorType", "Message", "Exception", "ParsingError", });
    internal_static_exec_shared_ExceptionWrapper_descriptor =
      getDescriptor().getMessageTypes().get(3);
    internal_static_exec_shared_ExceptionWrapper_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_ExceptionWrapper_descriptor,
        new java.lang.String[] { "ExceptionClass", "Message", "StackTrace", "Cause", });
    internal_static_exec_shared_StackTraceElementWrapper_descriptor =
      getDescriptor().getMessageTypes().get(4);
    internal_static_exec_shared_StackTraceElementWrapper_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_StackTraceElementWrapper_descriptor,
        new java.lang.String[] { "ClassName", "FileName", "LineNumber", "MethodName", "IsNativeMethod", });
    internal_static_exec_shared_ParsingError_descriptor =
      getDescriptor().getMessageTypes().get(5);
    internal_static_exec_shared_ParsingError_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_ParsingError_descriptor,
        new java.lang.String[] { "StartColumn", "StartRow", "EndColumn", "EndRow", });
    internal_static_exec_shared_RecordBatchDef_descriptor =
      getDescriptor().getMessageTypes().get(6);
    internal_static_exec_shared_RecordBatchDef_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_RecordBatchDef_descriptor,
        new java.lang.String[] { "RecordCount", "Field", "CarriesTwoByteSelectionVector", "AffectedRowsCount", });
    internal_static_exec_shared_NamePart_descriptor =
      getDescriptor().getMessageTypes().get(7);
    internal_static_exec_shared_NamePart_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_NamePart_descriptor,
        new java.lang.String[] { "Type", "Name", "Child", });
    internal_static_exec_shared_SerializedField_descriptor =
      getDescriptor().getMessageTypes().get(8);
    internal_static_exec_shared_SerializedField_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_SerializedField_descriptor,
        new java.lang.String[] { "MajorType", "NamePart", "Child", "ValueCount", "VarByteLength", "BufferLength", });
    internal_static_exec_shared_NodeStatus_descriptor =
      getDescriptor().getMessageTypes().get(9);
    internal_static_exec_shared_NodeStatus_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_NodeStatus_descriptor,
        new java.lang.String[] { "NodeId", "MemoryFootprint", });
    internal_static_exec_shared_QueryResult_descriptor =
      getDescriptor().getMessageTypes().get(10);
    internal_static_exec_shared_QueryResult_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_QueryResult_descriptor,
        new java.lang.String[] { "QueryState", "QueryId", "Error", });
    internal_static_exec_shared_QueryData_descriptor =
      getDescriptor().getMessageTypes().get(11);
    internal_static_exec_shared_QueryData_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_QueryData_descriptor,
        new java.lang.String[] { "QueryId", "RowCount", "Def", "AffectedRowsCount", });
    internal_static_exec_shared_QueryInfo_descriptor =
      getDescriptor().getMessageTypes().get(12);
    internal_static_exec_shared_QueryInfo_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_QueryInfo_descriptor,
        new java.lang.String[] { "Query", "Start", "State", "User", "Foreman", "OptionsJson", "TotalCost", "QueueName", });
    internal_static_exec_shared_QueryProfile_descriptor =
      getDescriptor().getMessageTypes().get(13);
    internal_static_exec_shared_QueryProfile_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_shared_QueryProfile_descriptor,
        new java.lang.String[] { "Id", "Type", "Start", "End", "Query", "Plan", "Foreman", "State", "TotalFragments", "FinishedFragments", "FragmentProfile", "User", "Error", "VerboseError", "ErrorId", "ErrorNode", "OptionsJson", "PlanEnd", "QueueWaitEnd", "TotalCost", "QueueName", "QueryId", "AutoLimit", });
    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)
}
