/*
 * 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: BitControl.proto

package org.apache.drill.exec.proto;

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

  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistry registry) {
    registerAllExtensions(
        (com.google.protobuf.ExtensionRegistryLite) registry);
  }
  /**
   * <pre>
   *&#47;/// BitControl RPC ///////
   * </pre>
   *
   * Protobuf enum {@code exec.bit.control.RpcType}
   */
  public enum RpcType
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <code>HANDSHAKE = 0;</code>
     */
    HANDSHAKE(0),
    /**
     * <code>ACK = 1;</code>
     */
    ACK(1),
    /**
     * <code>GOODBYE = 2;</code>
     */
    GOODBYE(2),
    /**
     * <pre>
     * bit requests
     * </pre>
     *
     * <code>REQ_INITIALIZE_FRAGMENTS = 3;</code>
     */
    REQ_INITIALIZE_FRAGMENTS(3),
    /**
     * <pre>
     * send a cancellation message for a fragment, returns Ack
     * </pre>
     *
     * <code>REQ_CANCEL_FRAGMENT = 6;</code>
     */
    REQ_CANCEL_FRAGMENT(6),
    /**
     * <code>REQ_RECEIVER_FINISHED = 7;</code>
     */
    REQ_RECEIVER_FINISHED(7),
    /**
     * <pre>
     * send a fragment status, return Ack
     * </pre>
     *
     * <code>REQ_FRAGMENT_STATUS = 8;</code>
     */
    REQ_FRAGMENT_STATUS(8),
    /**
     * <pre>
     * get bit status.
     * </pre>
     *
     * <code>REQ_BIT_STATUS = 9;</code>
     */
    REQ_BIT_STATUS(9),
    /**
     * <code>REQ_QUERY_STATUS = 10;</code>
     */
    REQ_QUERY_STATUS(10),
    /**
     * <code>REQ_QUERY_CANCEL = 15;</code>
     */
    REQ_QUERY_CANCEL(15),
    /**
     * <pre>
     * send a resume message for a fragment, returns Ack
     * </pre>
     *
     * <code>REQ_UNPAUSE_FRAGMENT = 16;</code>
     */
    REQ_UNPAUSE_FRAGMENT(16),
    /**
     * <code>REQ_CUSTOM = 17;</code>
     */
    REQ_CUSTOM(17),
    /**
     * <pre>
     * bit responses
     * </pre>
     *
     * <code>RESP_FRAGMENT_HANDLE = 11;</code>
     */
    RESP_FRAGMENT_HANDLE(11),
    /**
     * <code>RESP_FRAGMENT_STATUS = 12;</code>
     */
    RESP_FRAGMENT_STATUS(12),
    /**
     * <code>RESP_BIT_STATUS = 13;</code>
     */
    RESP_BIT_STATUS(13),
    /**
     * <code>RESP_QUERY_STATUS = 14;</code>
     */
    RESP_QUERY_STATUS(14),
    /**
     * <code>RESP_CUSTOM = 18;</code>
     */
    RESP_CUSTOM(18),
    /**
     * <pre>
     * both bit request and response
     * </pre>
     *
     * <code>SASL_MESSAGE = 19;</code>
     */
    SASL_MESSAGE(19),
    ;

    /**
     * <code>HANDSHAKE = 0;</code>
     */
    public static final int HANDSHAKE_VALUE = 0;
    /**
     * <code>ACK = 1;</code>
     */
    public static final int ACK_VALUE = 1;
    /**
     * <code>GOODBYE = 2;</code>
     */
    public static final int GOODBYE_VALUE = 2;
    /**
     * <pre>
     * bit requests
     * </pre>
     *
     * <code>REQ_INITIALIZE_FRAGMENTS = 3;</code>
     */
    public static final int REQ_INITIALIZE_FRAGMENTS_VALUE = 3;
    /**
     * <pre>
     * send a cancellation message for a fragment, returns Ack
     * </pre>
     *
     * <code>REQ_CANCEL_FRAGMENT = 6;</code>
     */
    public static final int REQ_CANCEL_FRAGMENT_VALUE = 6;
    /**
     * <code>REQ_RECEIVER_FINISHED = 7;</code>
     */
    public static final int REQ_RECEIVER_FINISHED_VALUE = 7;
    /**
     * <pre>
     * send a fragment status, return Ack
     * </pre>
     *
     * <code>REQ_FRAGMENT_STATUS = 8;</code>
     */
    public static final int REQ_FRAGMENT_STATUS_VALUE = 8;
    /**
     * <pre>
     * get bit status.
     * </pre>
     *
     * <code>REQ_BIT_STATUS = 9;</code>
     */
    public static final int REQ_BIT_STATUS_VALUE = 9;
    /**
     * <code>REQ_QUERY_STATUS = 10;</code>
     */
    public static final int REQ_QUERY_STATUS_VALUE = 10;
    /**
     * <code>REQ_QUERY_CANCEL = 15;</code>
     */
    public static final int REQ_QUERY_CANCEL_VALUE = 15;
    /**
     * <pre>
     * send a resume message for a fragment, returns Ack
     * </pre>
     *
     * <code>REQ_UNPAUSE_FRAGMENT = 16;</code>
     */
    public static final int REQ_UNPAUSE_FRAGMENT_VALUE = 16;
    /**
     * <code>REQ_CUSTOM = 17;</code>
     */
    public static final int REQ_CUSTOM_VALUE = 17;
    /**
     * <pre>
     * bit responses
     * </pre>
     *
     * <code>RESP_FRAGMENT_HANDLE = 11;</code>
     */
    public static final int RESP_FRAGMENT_HANDLE_VALUE = 11;
    /**
     * <code>RESP_FRAGMENT_STATUS = 12;</code>
     */
    public static final int RESP_FRAGMENT_STATUS_VALUE = 12;
    /**
     * <code>RESP_BIT_STATUS = 13;</code>
     */
    public static final int RESP_BIT_STATUS_VALUE = 13;
    /**
     * <code>RESP_QUERY_STATUS = 14;</code>
     */
    public static final int RESP_QUERY_STATUS_VALUE = 14;
    /**
     * <code>RESP_CUSTOM = 18;</code>
     */
    public static final int RESP_CUSTOM_VALUE = 18;
    /**
     * <pre>
     * both bit request and response
     * </pre>
     *
     * <code>SASL_MESSAGE = 19;</code>
     */
    public static final int SASL_MESSAGE_VALUE = 19;


    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 RpcType 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 RpcType forNumber(int value) {
      switch (value) {
        case 0: return HANDSHAKE;
        case 1: return ACK;
        case 2: return GOODBYE;
        case 3: return REQ_INITIALIZE_FRAGMENTS;
        case 6: return REQ_CANCEL_FRAGMENT;
        case 7: return REQ_RECEIVER_FINISHED;
        case 8: return REQ_FRAGMENT_STATUS;
        case 9: return REQ_BIT_STATUS;
        case 10: return REQ_QUERY_STATUS;
        case 15: return REQ_QUERY_CANCEL;
        case 16: return REQ_UNPAUSE_FRAGMENT;
        case 17: return REQ_CUSTOM;
        case 11: return RESP_FRAGMENT_HANDLE;
        case 12: return RESP_FRAGMENT_STATUS;
        case 13: return RESP_BIT_STATUS;
        case 14: return RESP_QUERY_STATUS;
        case 18: return RESP_CUSTOM;
        case 19: return SASL_MESSAGE;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<RpcType>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        RpcType> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<RpcType>() {
            public RpcType findValueByNumber(int number) {
              return RpcType.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.BitControl.getDescriptor().getEnumTypes().get(0);
    }

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

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

    // @@protoc_insertion_point(enum_scope:exec.bit.control.RpcType)
  }

  public interface BitControlHandshakeOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.bit.control.BitControlHandshake)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional int32 rpc_version = 1;</code>
     * @return Whether the rpcVersion field is set.
     */
    boolean hasRpcVersion();
    /**
     * <code>optional int32 rpc_version = 1;</code>
     * @return The rpcVersion.
     */
    int getRpcVersion();

    /**
     * <code>optional .exec.shared.RpcChannel channel = 2 [default = BIT_CONTROL];</code>
     * @return Whether the channel field is set.
     */
    boolean hasChannel();
    /**
     * <code>optional .exec.shared.RpcChannel channel = 2 [default = BIT_CONTROL];</code>
     * @return The channel.
     */
    org.apache.drill.exec.proto.UserBitShared.RpcChannel getChannel();

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

    /**
     * <code>repeated string authenticationMechanisms = 4;</code>
     * @return A list containing the authenticationMechanisms.
     */
    java.util.List<java.lang.String>
        getAuthenticationMechanismsList();
    /**
     * <code>repeated string authenticationMechanisms = 4;</code>
     * @return The count of authenticationMechanisms.
     */
    int getAuthenticationMechanismsCount();
    /**
     * <code>repeated string authenticationMechanisms = 4;</code>
     * @param index The index of the element to return.
     * @return The authenticationMechanisms at the given index.
     */
    java.lang.String getAuthenticationMechanisms(int index);
    /**
     * <code>repeated string authenticationMechanisms = 4;</code>
     * @param index The index of the value to return.
     * @return The bytes of the authenticationMechanisms at the given index.
     */
    com.google.protobuf.ByteString
        getAuthenticationMechanismsBytes(int index);
  }
  /**
   * Protobuf type {@code exec.bit.control.BitControlHandshake}
   */
  public static final class BitControlHandshake extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.bit.control.BitControlHandshake)
      BitControlHandshakeOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use BitControlHandshake.newBuilder() to construct.
    private BitControlHandshake(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private BitControlHandshake() {
      channel_ = 0;
      authenticationMechanisms_ = com.google.protobuf.LazyStringArrayList.EMPTY;
    }

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

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

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

    private int bitField0_;
    public static final int RPC_VERSION_FIELD_NUMBER = 1;
    private int rpcVersion_;
    /**
     * <code>optional int32 rpc_version = 1;</code>
     * @return Whether the rpcVersion field is set.
     */
    @java.lang.Override
    public boolean hasRpcVersion() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional int32 rpc_version = 1;</code>
     * @return The rpcVersion.
     */
    @java.lang.Override
    public int getRpcVersion() {
      return rpcVersion_;
    }

    public static final int CHANNEL_FIELD_NUMBER = 2;
    private int channel_;
    /**
     * <code>optional .exec.shared.RpcChannel channel = 2 [default = BIT_CONTROL];</code>
     * @return Whether the channel field is set.
     */
    @java.lang.Override public boolean hasChannel() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .exec.shared.RpcChannel channel = 2 [default = BIT_CONTROL];</code>
     * @return The channel.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserBitShared.RpcChannel getChannel() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserBitShared.RpcChannel result = org.apache.drill.exec.proto.UserBitShared.RpcChannel.valueOf(channel_);
      return result == null ? org.apache.drill.exec.proto.UserBitShared.RpcChannel.BIT_CONTROL : result;
    }

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

    public static final int AUTHENTICATIONMECHANISMS_FIELD_NUMBER = 4;
    private com.google.protobuf.LazyStringList authenticationMechanisms_;
    /**
     * <code>repeated string authenticationMechanisms = 4;</code>
     * @return A list containing the authenticationMechanisms.
     */
    public com.google.protobuf.ProtocolStringList
        getAuthenticationMechanismsList() {
      return authenticationMechanisms_;
    }
    /**
     * <code>repeated string authenticationMechanisms = 4;</code>
     * @return The count of authenticationMechanisms.
     */
    public int getAuthenticationMechanismsCount() {
      return authenticationMechanisms_.size();
    }
    /**
     * <code>repeated string authenticationMechanisms = 4;</code>
     * @param index The index of the element to return.
     * @return The authenticationMechanisms at the given index.
     */
    public java.lang.String getAuthenticationMechanisms(int index) {
      return authenticationMechanisms_.get(index);
    }
    /**
     * <code>repeated string authenticationMechanisms = 4;</code>
     * @param index The index of the value to return.
     * @return The bytes of the authenticationMechanisms at the given index.
     */
    public com.google.protobuf.ByteString
        getAuthenticationMechanismsBytes(int index) {
      return authenticationMechanisms_.getByteString(index);
    }

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

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeInt32(1, rpcVersion_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeEnum(2, channel_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeMessage(3, getEndpoint());
      }
      for (int i = 0; i < authenticationMechanisms_.size(); i++) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 4, authenticationMechanisms_.getRaw(i));
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(1, rpcVersion_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(2, channel_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, getEndpoint());
      }
      {
        int dataSize = 0;
        for (int i = 0; i < authenticationMechanisms_.size(); i++) {
          dataSize += computeStringSizeNoTag(authenticationMechanisms_.getRaw(i));
        }
        size += dataSize;
        size += 1 * getAuthenticationMechanismsList().size();
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.BitControl.BitControlHandshake)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.BitControl.BitControlHandshake other = (org.apache.drill.exec.proto.BitControl.BitControlHandshake) obj;

      if (hasRpcVersion() != other.hasRpcVersion()) return false;
      if (hasRpcVersion()) {
        if (getRpcVersion()
            != other.getRpcVersion()) return false;
      }
      if (hasChannel() != other.hasChannel()) return false;
      if (hasChannel()) {
        if (channel_ != other.channel_) return false;
      }
      if (hasEndpoint() != other.hasEndpoint()) return false;
      if (hasEndpoint()) {
        if (!getEndpoint()
            .equals(other.getEndpoint())) return false;
      }
      if (!getAuthenticationMechanismsList()
          .equals(other.getAuthenticationMechanismsList())) return false;
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasRpcVersion()) {
        hash = (37 * hash) + RPC_VERSION_FIELD_NUMBER;
        hash = (53 * hash) + getRpcVersion();
      }
      if (hasChannel()) {
        hash = (37 * hash) + CHANNEL_FIELD_NUMBER;
        hash = (53 * hash) + channel_;
      }
      if (hasEndpoint()) {
        hash = (37 * hash) + ENDPOINT_FIELD_NUMBER;
        hash = (53 * hash) + getEndpoint().hashCode();
      }
      if (getAuthenticationMechanismsCount() > 0) {
        hash = (37 * hash) + AUTHENTICATIONMECHANISMS_FIELD_NUMBER;
        hash = (53 * hash) + getAuthenticationMechanismsList().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

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

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

      // Construct using org.apache.drill.exec.proto.BitControl.BitControlHandshake.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();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        rpcVersion_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        channel_ = 0;
        bitField0_ = (bitField0_ & ~0x00000002);
        if (endpointBuilder_ == null) {
          endpoint_ = null;
        } else {
          endpointBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        authenticationMechanisms_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }

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

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

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

      @java.lang.Override
      public org.apache.drill.exec.proto.BitControl.BitControlHandshake buildPartial() {
        org.apache.drill.exec.proto.BitControl.BitControlHandshake result = new org.apache.drill.exec.proto.BitControl.BitControlHandshake(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.rpcVersion_ = rpcVersion_;
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          to_bitField0_ |= 0x00000002;
        }
        result.channel_ = channel_;
        if (((from_bitField0_ & 0x00000004) != 0)) {
          if (endpointBuilder_ == null) {
            result.endpoint_ = endpoint_;
          } else {
            result.endpoint_ = endpointBuilder_.build();
          }
          to_bitField0_ |= 0x00000004;
        }
        if (((bitField0_ & 0x00000008) != 0)) {
          authenticationMechanisms_ = authenticationMechanisms_.getUnmodifiableView();
          bitField0_ = (bitField0_ & ~0x00000008);
        }
        result.authenticationMechanisms_ = authenticationMechanisms_;
        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.BitControl.BitControlHandshake) {
          return mergeFrom((org.apache.drill.exec.proto.BitControl.BitControlHandshake)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.BitControl.BitControlHandshake other) {
        if (other == org.apache.drill.exec.proto.BitControl.BitControlHandshake.getDefaultInstance()) return this;
        if (other.hasRpcVersion()) {
          setRpcVersion(other.getRpcVersion());
        }
        if (other.hasChannel()) {
          setChannel(other.getChannel());
        }
        if (other.hasEndpoint()) {
          mergeEndpoint(other.getEndpoint());
        }
        if (!other.authenticationMechanisms_.isEmpty()) {
          if (authenticationMechanisms_.isEmpty()) {
            authenticationMechanisms_ = other.authenticationMechanisms_;
            bitField0_ = (bitField0_ & ~0x00000008);
          } else {
            ensureAuthenticationMechanismsIsMutable();
            authenticationMechanisms_.addAll(other.authenticationMechanisms_);
          }
          onChanged();
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                rpcVersion_ = input.readInt32();
                bitField0_ |= 0x00000001;
                break;
              } // case 8
              case 16: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserBitShared.RpcChannel tmpValue =
                    org.apache.drill.exec.proto.UserBitShared.RpcChannel.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(2, tmpRaw);
                } else {
                  channel_ = tmpRaw;
                  bitField0_ |= 0x00000002;
                }
                break;
              } // case 16
              case 26: {
                input.readMessage(
                    getEndpointFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000004;
                break;
              } // case 26
              case 34: {
                com.google.protobuf.ByteString bs = input.readBytes();
                ensureAuthenticationMechanismsIsMutable();
                authenticationMechanisms_.add(bs);
                break;
              } // case 34
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private int rpcVersion_ ;
      /**
       * <code>optional int32 rpc_version = 1;</code>
       * @return Whether the rpcVersion field is set.
       */
      @java.lang.Override
      public boolean hasRpcVersion() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional int32 rpc_version = 1;</code>
       * @return The rpcVersion.
       */
      @java.lang.Override
      public int getRpcVersion() {
        return rpcVersion_;
      }
      /**
       * <code>optional int32 rpc_version = 1;</code>
       * @param value The rpcVersion to set.
       * @return This builder for chaining.
       */
      public Builder setRpcVersion(int value) {
        bitField0_ |= 0x00000001;
        rpcVersion_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 rpc_version = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearRpcVersion() {
        bitField0_ = (bitField0_ & ~0x00000001);
        rpcVersion_ = 0;
        onChanged();
        return this;
      }

      private int channel_ = 0;
      /**
       * <code>optional .exec.shared.RpcChannel channel = 2 [default = BIT_CONTROL];</code>
       * @return Whether the channel field is set.
       */
      @java.lang.Override public boolean hasChannel() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional .exec.shared.RpcChannel channel = 2 [default = BIT_CONTROL];</code>
       * @return The channel.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.RpcChannel getChannel() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserBitShared.RpcChannel result = org.apache.drill.exec.proto.UserBitShared.RpcChannel.valueOf(channel_);
        return result == null ? org.apache.drill.exec.proto.UserBitShared.RpcChannel.BIT_CONTROL : result;
      }
      /**
       * <code>optional .exec.shared.RpcChannel channel = 2 [default = BIT_CONTROL];</code>
       * @param value The channel to set.
       * @return This builder for chaining.
       */
      public Builder setChannel(org.apache.drill.exec.proto.UserBitShared.RpcChannel value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000002;
        channel_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .exec.shared.RpcChannel channel = 2 [default = BIT_CONTROL];</code>
       * @return This builder for chaining.
       */
      public Builder clearChannel() {
        bitField0_ = (bitField0_ & ~0x00000002);
        channel_ = 0;
        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 = 3;</code>
       * @return Whether the endpoint field is set.
       */
      public boolean hasEndpoint() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 3;</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 = 3;</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_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 3;</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_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 3;</code>
       */
      public Builder mergeEndpoint(org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint value) {
        if (endpointBuilder_ == null) {
          if (((bitField0_ & 0x00000004) != 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_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 3;</code>
       */
      public Builder clearEndpoint() {
        if (endpointBuilder_ == null) {
          endpoint_ = null;
          onChanged();
        } else {
          endpointBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 3;</code>
       */
      public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder getEndpointBuilder() {
        bitField0_ |= 0x00000004;
        onChanged();
        return getEndpointFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 3;</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 = 3;</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 com.google.protobuf.LazyStringList authenticationMechanisms_ = com.google.protobuf.LazyStringArrayList.EMPTY;
      private void ensureAuthenticationMechanismsIsMutable() {
        if (!((bitField0_ & 0x00000008) != 0)) {
          authenticationMechanisms_ = new com.google.protobuf.LazyStringArrayList(authenticationMechanisms_);
          bitField0_ |= 0x00000008;
         }
      }
      /**
       * <code>repeated string authenticationMechanisms = 4;</code>
       * @return A list containing the authenticationMechanisms.
       */
      public com.google.protobuf.ProtocolStringList
          getAuthenticationMechanismsList() {
        return authenticationMechanisms_.getUnmodifiableView();
      }
      /**
       * <code>repeated string authenticationMechanisms = 4;</code>
       * @return The count of authenticationMechanisms.
       */
      public int getAuthenticationMechanismsCount() {
        return authenticationMechanisms_.size();
      }
      /**
       * <code>repeated string authenticationMechanisms = 4;</code>
       * @param index The index of the element to return.
       * @return The authenticationMechanisms at the given index.
       */
      public java.lang.String getAuthenticationMechanisms(int index) {
        return authenticationMechanisms_.get(index);
      }
      /**
       * <code>repeated string authenticationMechanisms = 4;</code>
       * @param index The index of the value to return.
       * @return The bytes of the authenticationMechanisms at the given index.
       */
      public com.google.protobuf.ByteString
          getAuthenticationMechanismsBytes(int index) {
        return authenticationMechanisms_.getByteString(index);
      }
      /**
       * <code>repeated string authenticationMechanisms = 4;</code>
       * @param index The index to set the value at.
       * @param value The authenticationMechanisms to set.
       * @return This builder for chaining.
       */
      public Builder setAuthenticationMechanisms(
          int index, java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureAuthenticationMechanismsIsMutable();
        authenticationMechanisms_.set(index, value);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string authenticationMechanisms = 4;</code>
       * @param value The authenticationMechanisms to add.
       * @return This builder for chaining.
       */
      public Builder addAuthenticationMechanisms(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureAuthenticationMechanismsIsMutable();
        authenticationMechanisms_.add(value);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string authenticationMechanisms = 4;</code>
       * @param values The authenticationMechanisms to add.
       * @return This builder for chaining.
       */
      public Builder addAllAuthenticationMechanisms(
          java.lang.Iterable<java.lang.String> values) {
        ensureAuthenticationMechanismsIsMutable();
        com.google.protobuf.AbstractMessageLite.Builder.addAll(
            values, authenticationMechanisms_);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string authenticationMechanisms = 4;</code>
       * @return This builder for chaining.
       */
      public Builder clearAuthenticationMechanisms() {
        authenticationMechanisms_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000008);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string authenticationMechanisms = 4;</code>
       * @param value The bytes of the authenticationMechanisms to add.
       * @return This builder for chaining.
       */
      public Builder addAuthenticationMechanismsBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureAuthenticationMechanismsIsMutable();
        authenticationMechanisms_.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.bit.control.BitControlHandshake)
    }

    // @@protoc_insertion_point(class_scope:exec.bit.control.BitControlHandshake)
    private static final org.apache.drill.exec.proto.BitControl.BitControlHandshake DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.BitControl.BitControlHandshake();
    }

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

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

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

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

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

  }

  public interface BitStatusOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.bit.control.BitStatus)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
     */
    java.util.List<org.apache.drill.exec.proto.BitControl.FragmentStatus> 
        getFragmentStatusList();
    /**
     * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
     */
    org.apache.drill.exec.proto.BitControl.FragmentStatus getFragmentStatus(int index);
    /**
     * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
     */
    int getFragmentStatusCount();
    /**
     * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
     */
    java.util.List<? extends org.apache.drill.exec.proto.BitControl.FragmentStatusOrBuilder> 
        getFragmentStatusOrBuilderList();
    /**
     * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
     */
    org.apache.drill.exec.proto.BitControl.FragmentStatusOrBuilder getFragmentStatusOrBuilder(
        int index);
  }
  /**
   * Protobuf type {@code exec.bit.control.BitStatus}
   */
  public static final class BitStatus extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.bit.control.BitStatus)
      BitStatusOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use BitStatus.newBuilder() to construct.
    private BitStatus(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private BitStatus() {
      fragmentStatus_ = java.util.Collections.emptyList();
    }

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

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

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

    public static final int FRAGMENT_STATUS_FIELD_NUMBER = 1;
    private java.util.List<org.apache.drill.exec.proto.BitControl.FragmentStatus> fragmentStatus_;
    /**
     * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.BitControl.FragmentStatus> getFragmentStatusList() {
      return fragmentStatus_;
    }
    /**
     * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
     */
    @java.lang.Override
    public java.util.List<? extends org.apache.drill.exec.proto.BitControl.FragmentStatusOrBuilder> 
        getFragmentStatusOrBuilderList() {
      return fragmentStatus_;
    }
    /**
     * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
     */
    @java.lang.Override
    public int getFragmentStatusCount() {
      return fragmentStatus_.size();
    }
    /**
     * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.BitControl.FragmentStatus getFragmentStatus(int index) {
      return fragmentStatus_.get(index);
    }
    /**
     * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.BitControl.FragmentStatusOrBuilder getFragmentStatusOrBuilder(
        int index) {
      return fragmentStatus_.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 < fragmentStatus_.size(); i++) {
        output.writeMessage(1, fragmentStatus_.get(i));
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      for (int i = 0; i < fragmentStatus_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, fragmentStatus_.get(i));
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.BitControl.BitStatus)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.BitControl.BitStatus other = (org.apache.drill.exec.proto.BitControl.BitStatus) obj;

      if (!getFragmentStatusList()
          .equals(other.getFragmentStatusList())) return false;
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

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

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

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

      // Construct using org.apache.drill.exec.proto.BitControl.BitStatus.newBuilder()
      private Builder() {

      }

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

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

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

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

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

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

      public Builder mergeFrom(org.apache.drill.exec.proto.BitControl.BitStatus other) {
        if (other == org.apache.drill.exec.proto.BitControl.BitStatus.getDefaultInstance()) return this;
        if (fragmentStatusBuilder_ == null) {
          if (!other.fragmentStatus_.isEmpty()) {
            if (fragmentStatus_.isEmpty()) {
              fragmentStatus_ = other.fragmentStatus_;
              bitField0_ = (bitField0_ & ~0x00000001);
            } else {
              ensureFragmentStatusIsMutable();
              fragmentStatus_.addAll(other.fragmentStatus_);
            }
            onChanged();
          }
        } else {
          if (!other.fragmentStatus_.isEmpty()) {
            if (fragmentStatusBuilder_.isEmpty()) {
              fragmentStatusBuilder_.dispose();
              fragmentStatusBuilder_ = null;
              fragmentStatus_ = other.fragmentStatus_;
              bitField0_ = (bitField0_ & ~0x00000001);
              fragmentStatusBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getFragmentStatusFieldBuilder() : null;
            } else {
              fragmentStatusBuilder_.addAllMessages(other.fragmentStatus_);
            }
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                org.apache.drill.exec.proto.BitControl.FragmentStatus m =
                    input.readMessage(
                        org.apache.drill.exec.proto.BitControl.FragmentStatus.PARSER,
                        extensionRegistry);
                if (fragmentStatusBuilder_ == null) {
                  ensureFragmentStatusIsMutable();
                  fragmentStatus_.add(m);
                } else {
                  fragmentStatusBuilder_.addMessage(m);
                }
                break;
              } // case 10
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.util.List<org.apache.drill.exec.proto.BitControl.FragmentStatus> fragmentStatus_ =
        java.util.Collections.emptyList();
      private void ensureFragmentStatusIsMutable() {
        if (!((bitField0_ & 0x00000001) != 0)) {
          fragmentStatus_ = new java.util.ArrayList<org.apache.drill.exec.proto.BitControl.FragmentStatus>(fragmentStatus_);
          bitField0_ |= 0x00000001;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.BitControl.FragmentStatus, org.apache.drill.exec.proto.BitControl.FragmentStatus.Builder, org.apache.drill.exec.proto.BitControl.FragmentStatusOrBuilder> fragmentStatusBuilder_;

      /**
       * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.BitControl.FragmentStatus> getFragmentStatusList() {
        if (fragmentStatusBuilder_ == null) {
          return java.util.Collections.unmodifiableList(fragmentStatus_);
        } else {
          return fragmentStatusBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
       */
      public int getFragmentStatusCount() {
        if (fragmentStatusBuilder_ == null) {
          return fragmentStatus_.size();
        } else {
          return fragmentStatusBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
       */
      public org.apache.drill.exec.proto.BitControl.FragmentStatus getFragmentStatus(int index) {
        if (fragmentStatusBuilder_ == null) {
          return fragmentStatus_.get(index);
        } else {
          return fragmentStatusBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
       */
      public Builder setFragmentStatus(
          int index, org.apache.drill.exec.proto.BitControl.FragmentStatus value) {
        if (fragmentStatusBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureFragmentStatusIsMutable();
          fragmentStatus_.set(index, value);
          onChanged();
        } else {
          fragmentStatusBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
       */
      public Builder setFragmentStatus(
          int index, org.apache.drill.exec.proto.BitControl.FragmentStatus.Builder builderForValue) {
        if (fragmentStatusBuilder_ == null) {
          ensureFragmentStatusIsMutable();
          fragmentStatus_.set(index, builderForValue.build());
          onChanged();
        } else {
          fragmentStatusBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
       */
      public Builder addFragmentStatus(org.apache.drill.exec.proto.BitControl.FragmentStatus value) {
        if (fragmentStatusBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureFragmentStatusIsMutable();
          fragmentStatus_.add(value);
          onChanged();
        } else {
          fragmentStatusBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
       */
      public Builder addFragmentStatus(
          int index, org.apache.drill.exec.proto.BitControl.FragmentStatus value) {
        if (fragmentStatusBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureFragmentStatusIsMutable();
          fragmentStatus_.add(index, value);
          onChanged();
        } else {
          fragmentStatusBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
       */
      public Builder addFragmentStatus(
          org.apache.drill.exec.proto.BitControl.FragmentStatus.Builder builderForValue) {
        if (fragmentStatusBuilder_ == null) {
          ensureFragmentStatusIsMutable();
          fragmentStatus_.add(builderForValue.build());
          onChanged();
        } else {
          fragmentStatusBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
       */
      public Builder addFragmentStatus(
          int index, org.apache.drill.exec.proto.BitControl.FragmentStatus.Builder builderForValue) {
        if (fragmentStatusBuilder_ == null) {
          ensureFragmentStatusIsMutable();
          fragmentStatus_.add(index, builderForValue.build());
          onChanged();
        } else {
          fragmentStatusBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
       */
      public Builder addAllFragmentStatus(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.BitControl.FragmentStatus> values) {
        if (fragmentStatusBuilder_ == null) {
          ensureFragmentStatusIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, fragmentStatus_);
          onChanged();
        } else {
          fragmentStatusBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
       */
      public Builder clearFragmentStatus() {
        if (fragmentStatusBuilder_ == null) {
          fragmentStatus_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
          onChanged();
        } else {
          fragmentStatusBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
       */
      public Builder removeFragmentStatus(int index) {
        if (fragmentStatusBuilder_ == null) {
          ensureFragmentStatusIsMutable();
          fragmentStatus_.remove(index);
          onChanged();
        } else {
          fragmentStatusBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
       */
      public org.apache.drill.exec.proto.BitControl.FragmentStatus.Builder getFragmentStatusBuilder(
          int index) {
        return getFragmentStatusFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
       */
      public org.apache.drill.exec.proto.BitControl.FragmentStatusOrBuilder getFragmentStatusOrBuilder(
          int index) {
        if (fragmentStatusBuilder_ == null) {
          return fragmentStatus_.get(index);  } else {
          return fragmentStatusBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
       */
      public java.util.List<? extends org.apache.drill.exec.proto.BitControl.FragmentStatusOrBuilder> 
           getFragmentStatusOrBuilderList() {
        if (fragmentStatusBuilder_ != null) {
          return fragmentStatusBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(fragmentStatus_);
        }
      }
      /**
       * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
       */
      public org.apache.drill.exec.proto.BitControl.FragmentStatus.Builder addFragmentStatusBuilder() {
        return getFragmentStatusFieldBuilder().addBuilder(
            org.apache.drill.exec.proto.BitControl.FragmentStatus.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
       */
      public org.apache.drill.exec.proto.BitControl.FragmentStatus.Builder addFragmentStatusBuilder(
          int index) {
        return getFragmentStatusFieldBuilder().addBuilder(
            index, org.apache.drill.exec.proto.BitControl.FragmentStatus.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.bit.control.FragmentStatus fragment_status = 1;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.BitControl.FragmentStatus.Builder> 
           getFragmentStatusBuilderList() {
        return getFragmentStatusFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.BitControl.FragmentStatus, org.apache.drill.exec.proto.BitControl.FragmentStatus.Builder, org.apache.drill.exec.proto.BitControl.FragmentStatusOrBuilder> 
          getFragmentStatusFieldBuilder() {
        if (fragmentStatusBuilder_ == null) {
          fragmentStatusBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              org.apache.drill.exec.proto.BitControl.FragmentStatus, org.apache.drill.exec.proto.BitControl.FragmentStatus.Builder, org.apache.drill.exec.proto.BitControl.FragmentStatusOrBuilder>(
                  fragmentStatus_,
                  ((bitField0_ & 0x00000001) != 0),
                  getParentForChildren(),
                  isClean());
          fragmentStatus_ = null;
        }
        return fragmentStatusBuilder_;
      }
      @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.bit.control.BitStatus)
    }

    // @@protoc_insertion_point(class_scope:exec.bit.control.BitStatus)
    private static final org.apache.drill.exec.proto.BitControl.BitStatus DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.BitControl.BitStatus();
    }

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

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

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

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

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

  }

  public interface FragmentStatusOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.bit.control.FragmentStatus)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional .exec.shared.MinorFragmentProfile profile = 1;</code>
     * @return Whether the profile field is set.
     */
    boolean hasProfile();
    /**
     * <code>optional .exec.shared.MinorFragmentProfile profile = 1;</code>
     * @return The profile.
     */
    org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile getProfile();
    /**
     * <code>optional .exec.shared.MinorFragmentProfile profile = 1;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfileOrBuilder getProfileOrBuilder();

    /**
     * <code>optional .exec.bit.FragmentHandle handle = 2;</code>
     * @return Whether the handle field is set.
     */
    boolean hasHandle();
    /**
     * <code>optional .exec.bit.FragmentHandle handle = 2;</code>
     * @return The handle.
     */
    org.apache.drill.exec.proto.ExecProtos.FragmentHandle getHandle();
    /**
     * <code>optional .exec.bit.FragmentHandle handle = 2;</code>
     */
    org.apache.drill.exec.proto.ExecProtos.FragmentHandleOrBuilder getHandleOrBuilder();
  }
  /**
   * Protobuf type {@code exec.bit.control.FragmentStatus}
   */
  public static final class FragmentStatus extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.bit.control.FragmentStatus)
      FragmentStatusOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use FragmentStatus.newBuilder() to construct.
    private FragmentStatus(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private FragmentStatus() {
    }

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

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

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

    private int bitField0_;
    public static final int PROFILE_FIELD_NUMBER = 1;
    private org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile profile_;
    /**
     * <code>optional .exec.shared.MinorFragmentProfile profile = 1;</code>
     * @return Whether the profile field is set.
     */
    @java.lang.Override
    public boolean hasProfile() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional .exec.shared.MinorFragmentProfile profile = 1;</code>
     * @return The profile.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile getProfile() {
      return profile_ == null ? org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.getDefaultInstance() : profile_;
    }
    /**
     * <code>optional .exec.shared.MinorFragmentProfile profile = 1;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfileOrBuilder getProfileOrBuilder() {
      return profile_ == null ? org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.getDefaultInstance() : profile_;
    }

    public static final int HANDLE_FIELD_NUMBER = 2;
    private org.apache.drill.exec.proto.ExecProtos.FragmentHandle handle_;
    /**
     * <code>optional .exec.bit.FragmentHandle handle = 2;</code>
     * @return Whether the handle field is set.
     */
    @java.lang.Override
    public boolean hasHandle() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .exec.bit.FragmentHandle handle = 2;</code>
     * @return The handle.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.ExecProtos.FragmentHandle getHandle() {
      return handle_ == null ? org.apache.drill.exec.proto.ExecProtos.FragmentHandle.getDefaultInstance() : handle_;
    }
    /**
     * <code>optional .exec.bit.FragmentHandle handle = 2;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.ExecProtos.FragmentHandleOrBuilder getHandleOrBuilder() {
      return handle_ == null ? org.apache.drill.exec.proto.ExecProtos.FragmentHandle.getDefaultInstance() : handle_;
    }

    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, getProfile());
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeMessage(2, getHandle());
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, getProfile());
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, getHandle());
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.BitControl.FragmentStatus)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.BitControl.FragmentStatus other = (org.apache.drill.exec.proto.BitControl.FragmentStatus) obj;

      if (hasProfile() != other.hasProfile()) return false;
      if (hasProfile()) {
        if (!getProfile()
            .equals(other.getProfile())) return false;
      }
      if (hasHandle() != other.hasHandle()) return false;
      if (hasHandle()) {
        if (!getHandle()
            .equals(other.getHandle())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasProfile()) {
        hash = (37 * hash) + PROFILE_FIELD_NUMBER;
        hash = (53 * hash) + getProfile().hashCode();
      }
      if (hasHandle()) {
        hash = (37 * hash) + HANDLE_FIELD_NUMBER;
        hash = (53 * hash) + getHandle().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

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

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

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

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getProfileFieldBuilder();
          getHandleFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        if (profileBuilder_ == null) {
          profile_ = null;
        } else {
          profileBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        if (handleBuilder_ == null) {
          handle_ = null;
        } else {
          handleBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

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

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

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

      @java.lang.Override
      public org.apache.drill.exec.proto.BitControl.FragmentStatus buildPartial() {
        org.apache.drill.exec.proto.BitControl.FragmentStatus result = new org.apache.drill.exec.proto.BitControl.FragmentStatus(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          if (profileBuilder_ == null) {
            result.profile_ = profile_;
          } else {
            result.profile_ = profileBuilder_.build();
          }
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          if (handleBuilder_ == null) {
            result.handle_ = handle_;
          } else {
            result.handle_ = handleBuilder_.build();
          }
          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.BitControl.FragmentStatus) {
          return mergeFrom((org.apache.drill.exec.proto.BitControl.FragmentStatus)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.BitControl.FragmentStatus other) {
        if (other == org.apache.drill.exec.proto.BitControl.FragmentStatus.getDefaultInstance()) return this;
        if (other.hasProfile()) {
          mergeProfile(other.getProfile());
        }
        if (other.hasHandle()) {
          mergeHandle(other.getHandle());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                input.readMessage(
                    getProfileFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 18: {
                input.readMessage(
                    getHandleFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile profile_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile, org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.Builder, org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfileOrBuilder> profileBuilder_;
      /**
       * <code>optional .exec.shared.MinorFragmentProfile profile = 1;</code>
       * @return Whether the profile field is set.
       */
      public boolean hasProfile() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .exec.shared.MinorFragmentProfile profile = 1;</code>
       * @return The profile.
       */
      public org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile getProfile() {
        if (profileBuilder_ == null) {
          return profile_ == null ? org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.getDefaultInstance() : profile_;
        } else {
          return profileBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.shared.MinorFragmentProfile profile = 1;</code>
       */
      public Builder setProfile(org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile value) {
        if (profileBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          profile_ = value;
          onChanged();
        } else {
          profileBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.shared.MinorFragmentProfile profile = 1;</code>
       */
      public Builder setProfile(
          org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.Builder builderForValue) {
        if (profileBuilder_ == null) {
          profile_ = builderForValue.build();
          onChanged();
        } else {
          profileBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.shared.MinorFragmentProfile profile = 1;</code>
       */
      public Builder mergeProfile(org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile value) {
        if (profileBuilder_ == null) {
          if (((bitField0_ & 0x00000001) != 0) &&
              profile_ != null &&
              profile_ != org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.getDefaultInstance()) {
            profile_ =
              org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.newBuilder(profile_).mergeFrom(value).buildPartial();
          } else {
            profile_ = value;
          }
          onChanged();
        } else {
          profileBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.shared.MinorFragmentProfile profile = 1;</code>
       */
      public Builder clearProfile() {
        if (profileBuilder_ == null) {
          profile_ = null;
          onChanged();
        } else {
          profileBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>optional .exec.shared.MinorFragmentProfile profile = 1;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.Builder getProfileBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getProfileFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.shared.MinorFragmentProfile profile = 1;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfileOrBuilder getProfileOrBuilder() {
        if (profileBuilder_ != null) {
          return profileBuilder_.getMessageOrBuilder();
        } else {
          return profile_ == null ?
              org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.getDefaultInstance() : profile_;
        }
      }
      /**
       * <code>optional .exec.shared.MinorFragmentProfile profile = 1;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile, org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.Builder, org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfileOrBuilder> 
          getProfileFieldBuilder() {
        if (profileBuilder_ == null) {
          profileBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile, org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfile.Builder, org.apache.drill.exec.proto.UserBitShared.MinorFragmentProfileOrBuilder>(
                  getProfile(),
                  getParentForChildren(),
                  isClean());
          profile_ = null;
        }
        return profileBuilder_;
      }

      private org.apache.drill.exec.proto.ExecProtos.FragmentHandle handle_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.ExecProtos.FragmentHandle, org.apache.drill.exec.proto.ExecProtos.FragmentHandle.Builder, org.apache.drill.exec.proto.ExecProtos.FragmentHandleOrBuilder> handleBuilder_;
      /**
       * <code>optional .exec.bit.FragmentHandle handle = 2;</code>
       * @return Whether the handle field is set.
       */
      public boolean hasHandle() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional .exec.bit.FragmentHandle handle = 2;</code>
       * @return The handle.
       */
      public org.apache.drill.exec.proto.ExecProtos.FragmentHandle getHandle() {
        if (handleBuilder_ == null) {
          return handle_ == null ? org.apache.drill.exec.proto.ExecProtos.FragmentHandle.getDefaultInstance() : handle_;
        } else {
          return handleBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.bit.FragmentHandle handle = 2;</code>
       */
      public Builder setHandle(org.apache.drill.exec.proto.ExecProtos.FragmentHandle value) {
        if (handleBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          handle_ = value;
          onChanged();
        } else {
          handleBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.bit.FragmentHandle handle = 2;</code>
       */
      public Builder setHandle(
          org.apache.drill.exec.proto.ExecProtos.FragmentHandle.Builder builderForValue) {
        if (handleBuilder_ == null) {
          handle_ = builderForValue.build();
          onChanged();
        } else {
          handleBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.bit.FragmentHandle handle = 2;</code>
       */
      public Builder mergeHandle(org.apache.drill.exec.proto.ExecProtos.FragmentHandle value) {
        if (handleBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0) &&
              handle_ != null &&
              handle_ != org.apache.drill.exec.proto.ExecProtos.FragmentHandle.getDefaultInstance()) {
            handle_ =
              org.apache.drill.exec.proto.ExecProtos.FragmentHandle.newBuilder(handle_).mergeFrom(value).buildPartial();
          } else {
            handle_ = value;
          }
          onChanged();
        } else {
          handleBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.bit.FragmentHandle handle = 2;</code>
       */
      public Builder clearHandle() {
        if (handleBuilder_ == null) {
          handle_ = null;
          onChanged();
        } else {
          handleBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>optional .exec.bit.FragmentHandle handle = 2;</code>
       */
      public org.apache.drill.exec.proto.ExecProtos.FragmentHandle.Builder getHandleBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getHandleFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.bit.FragmentHandle handle = 2;</code>
       */
      public org.apache.drill.exec.proto.ExecProtos.FragmentHandleOrBuilder getHandleOrBuilder() {
        if (handleBuilder_ != null) {
          return handleBuilder_.getMessageOrBuilder();
        } else {
          return handle_ == null ?
              org.apache.drill.exec.proto.ExecProtos.FragmentHandle.getDefaultInstance() : handle_;
        }
      }
      /**
       * <code>optional .exec.bit.FragmentHandle handle = 2;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.ExecProtos.FragmentHandle, org.apache.drill.exec.proto.ExecProtos.FragmentHandle.Builder, org.apache.drill.exec.proto.ExecProtos.FragmentHandleOrBuilder> 
          getHandleFieldBuilder() {
        if (handleBuilder_ == null) {
          handleBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.ExecProtos.FragmentHandle, org.apache.drill.exec.proto.ExecProtos.FragmentHandle.Builder, org.apache.drill.exec.proto.ExecProtos.FragmentHandleOrBuilder>(
                  getHandle(),
                  getParentForChildren(),
                  isClean());
          handle_ = null;
        }
        return handleBuilder_;
      }
      @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.bit.control.FragmentStatus)
    }

    // @@protoc_insertion_point(class_scope:exec.bit.control.FragmentStatus)
    private static final org.apache.drill.exec.proto.BitControl.FragmentStatus DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.BitControl.FragmentStatus();
    }

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

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

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

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

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

  }

  public interface InitializeFragmentsOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.bit.control.InitializeFragments)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
     */
    java.util.List<org.apache.drill.exec.proto.BitControl.PlanFragment> 
        getFragmentList();
    /**
     * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
     */
    org.apache.drill.exec.proto.BitControl.PlanFragment getFragment(int index);
    /**
     * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
     */
    int getFragmentCount();
    /**
     * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
     */
    java.util.List<? extends org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder> 
        getFragmentOrBuilderList();
    /**
     * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
     */
    org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder getFragmentOrBuilder(
        int index);
  }
  /**
   * Protobuf type {@code exec.bit.control.InitializeFragments}
   */
  public static final class InitializeFragments extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.bit.control.InitializeFragments)
      InitializeFragmentsOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use InitializeFragments.newBuilder() to construct.
    private InitializeFragments(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private InitializeFragments() {
      fragment_ = java.util.Collections.emptyList();
    }

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

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

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

    public static final int FRAGMENT_FIELD_NUMBER = 1;
    private java.util.List<org.apache.drill.exec.proto.BitControl.PlanFragment> fragment_;
    /**
     * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.BitControl.PlanFragment> getFragmentList() {
      return fragment_;
    }
    /**
     * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
     */
    @java.lang.Override
    public java.util.List<? extends org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder> 
        getFragmentOrBuilderList() {
      return fragment_;
    }
    /**
     * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
     */
    @java.lang.Override
    public int getFragmentCount() {
      return fragment_.size();
    }
    /**
     * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.BitControl.PlanFragment getFragment(int index) {
      return fragment_.get(index);
    }
    /**
     * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder getFragmentOrBuilder(
        int index) {
      return fragment_.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 < fragment_.size(); i++) {
        output.writeMessage(1, fragment_.get(i));
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      for (int i = 0; i < fragment_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, fragment_.get(i));
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.BitControl.InitializeFragments)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.BitControl.InitializeFragments other = (org.apache.drill.exec.proto.BitControl.InitializeFragments) obj;

      if (!getFragmentList()
          .equals(other.getFragmentList())) return false;
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

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

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

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

      // Construct using org.apache.drill.exec.proto.BitControl.InitializeFragments.newBuilder()
      private Builder() {

      }

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

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

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

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

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

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

      public Builder mergeFrom(org.apache.drill.exec.proto.BitControl.InitializeFragments other) {
        if (other == org.apache.drill.exec.proto.BitControl.InitializeFragments.getDefaultInstance()) return this;
        if (fragmentBuilder_ == null) {
          if (!other.fragment_.isEmpty()) {
            if (fragment_.isEmpty()) {
              fragment_ = other.fragment_;
              bitField0_ = (bitField0_ & ~0x00000001);
            } else {
              ensureFragmentIsMutable();
              fragment_.addAll(other.fragment_);
            }
            onChanged();
          }
        } else {
          if (!other.fragment_.isEmpty()) {
            if (fragmentBuilder_.isEmpty()) {
              fragmentBuilder_.dispose();
              fragmentBuilder_ = null;
              fragment_ = other.fragment_;
              bitField0_ = (bitField0_ & ~0x00000001);
              fragmentBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getFragmentFieldBuilder() : null;
            } else {
              fragmentBuilder_.addAllMessages(other.fragment_);
            }
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                org.apache.drill.exec.proto.BitControl.PlanFragment m =
                    input.readMessage(
                        org.apache.drill.exec.proto.BitControl.PlanFragment.PARSER,
                        extensionRegistry);
                if (fragmentBuilder_ == null) {
                  ensureFragmentIsMutable();
                  fragment_.add(m);
                } else {
                  fragmentBuilder_.addMessage(m);
                }
                break;
              } // case 10
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.util.List<org.apache.drill.exec.proto.BitControl.PlanFragment> fragment_ =
        java.util.Collections.emptyList();
      private void ensureFragmentIsMutable() {
        if (!((bitField0_ & 0x00000001) != 0)) {
          fragment_ = new java.util.ArrayList<org.apache.drill.exec.proto.BitControl.PlanFragment>(fragment_);
          bitField0_ |= 0x00000001;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.BitControl.PlanFragment, org.apache.drill.exec.proto.BitControl.PlanFragment.Builder, org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder> fragmentBuilder_;

      /**
       * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.BitControl.PlanFragment> getFragmentList() {
        if (fragmentBuilder_ == null) {
          return java.util.Collections.unmodifiableList(fragment_);
        } else {
          return fragmentBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
       */
      public int getFragmentCount() {
        if (fragmentBuilder_ == null) {
          return fragment_.size();
        } else {
          return fragmentBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
       */
      public org.apache.drill.exec.proto.BitControl.PlanFragment getFragment(int index) {
        if (fragmentBuilder_ == null) {
          return fragment_.get(index);
        } else {
          return fragmentBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
       */
      public Builder setFragment(
          int index, org.apache.drill.exec.proto.BitControl.PlanFragment value) {
        if (fragmentBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureFragmentIsMutable();
          fragment_.set(index, value);
          onChanged();
        } else {
          fragmentBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
       */
      public Builder setFragment(
          int index, org.apache.drill.exec.proto.BitControl.PlanFragment.Builder builderForValue) {
        if (fragmentBuilder_ == null) {
          ensureFragmentIsMutable();
          fragment_.set(index, builderForValue.build());
          onChanged();
        } else {
          fragmentBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
       */
      public Builder addFragment(org.apache.drill.exec.proto.BitControl.PlanFragment value) {
        if (fragmentBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureFragmentIsMutable();
          fragment_.add(value);
          onChanged();
        } else {
          fragmentBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
       */
      public Builder addFragment(
          int index, org.apache.drill.exec.proto.BitControl.PlanFragment value) {
        if (fragmentBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureFragmentIsMutable();
          fragment_.add(index, value);
          onChanged();
        } else {
          fragmentBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
       */
      public Builder addFragment(
          org.apache.drill.exec.proto.BitControl.PlanFragment.Builder builderForValue) {
        if (fragmentBuilder_ == null) {
          ensureFragmentIsMutable();
          fragment_.add(builderForValue.build());
          onChanged();
        } else {
          fragmentBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
       */
      public Builder addFragment(
          int index, org.apache.drill.exec.proto.BitControl.PlanFragment.Builder builderForValue) {
        if (fragmentBuilder_ == null) {
          ensureFragmentIsMutable();
          fragment_.add(index, builderForValue.build());
          onChanged();
        } else {
          fragmentBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
       */
      public Builder addAllFragment(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.BitControl.PlanFragment> values) {
        if (fragmentBuilder_ == null) {
          ensureFragmentIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, fragment_);
          onChanged();
        } else {
          fragmentBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
       */
      public Builder clearFragment() {
        if (fragmentBuilder_ == null) {
          fragment_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
          onChanged();
        } else {
          fragmentBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
       */
      public Builder removeFragment(int index) {
        if (fragmentBuilder_ == null) {
          ensureFragmentIsMutable();
          fragment_.remove(index);
          onChanged();
        } else {
          fragmentBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
       */
      public org.apache.drill.exec.proto.BitControl.PlanFragment.Builder getFragmentBuilder(
          int index) {
        return getFragmentFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
       */
      public org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder getFragmentOrBuilder(
          int index) {
        if (fragmentBuilder_ == null) {
          return fragment_.get(index);  } else {
          return fragmentBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
       */
      public java.util.List<? extends org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder> 
           getFragmentOrBuilderList() {
        if (fragmentBuilder_ != null) {
          return fragmentBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(fragment_);
        }
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
       */
      public org.apache.drill.exec.proto.BitControl.PlanFragment.Builder addFragmentBuilder() {
        return getFragmentFieldBuilder().addBuilder(
            org.apache.drill.exec.proto.BitControl.PlanFragment.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
       */
      public org.apache.drill.exec.proto.BitControl.PlanFragment.Builder addFragmentBuilder(
          int index) {
        return getFragmentFieldBuilder().addBuilder(
            index, org.apache.drill.exec.proto.BitControl.PlanFragment.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragment = 1;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.BitControl.PlanFragment.Builder> 
           getFragmentBuilderList() {
        return getFragmentFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.BitControl.PlanFragment, org.apache.drill.exec.proto.BitControl.PlanFragment.Builder, org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder> 
          getFragmentFieldBuilder() {
        if (fragmentBuilder_ == null) {
          fragmentBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              org.apache.drill.exec.proto.BitControl.PlanFragment, org.apache.drill.exec.proto.BitControl.PlanFragment.Builder, org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder>(
                  fragment_,
                  ((bitField0_ & 0x00000001) != 0),
                  getParentForChildren(),
                  isClean());
          fragment_ = null;
        }
        return fragmentBuilder_;
      }
      @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.bit.control.InitializeFragments)
    }

    // @@protoc_insertion_point(class_scope:exec.bit.control.InitializeFragments)
    private static final org.apache.drill.exec.proto.BitControl.InitializeFragments DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.BitControl.InitializeFragments();
    }

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

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

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

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

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

  }

  public interface CustomMessageOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.bit.control.CustomMessage)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional int32 type = 1;</code>
     * @return Whether the type field is set.
     */
    boolean hasType();
    /**
     * <code>optional int32 type = 1;</code>
     * @return The type.
     */
    int getType();

    /**
     * <code>optional bytes message = 2;</code>
     * @return Whether the message field is set.
     */
    boolean hasMessage();
    /**
     * <code>optional bytes message = 2;</code>
     * @return The message.
     */
    com.google.protobuf.ByteString getMessage();
  }
  /**
   * Protobuf type {@code exec.bit.control.CustomMessage}
   */
  public static final class CustomMessage extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.bit.control.CustomMessage)
      CustomMessageOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use CustomMessage.newBuilder() to construct.
    private CustomMessage(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private CustomMessage() {
      message_ = com.google.protobuf.ByteString.EMPTY;
    }

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

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

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

    private int bitField0_;
    public static final int TYPE_FIELD_NUMBER = 1;
    private int type_;
    /**
     * <code>optional int32 type = 1;</code>
     * @return Whether the type field is set.
     */
    @java.lang.Override
    public boolean hasType() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional int32 type = 1;</code>
     * @return The type.
     */
    @java.lang.Override
    public int getType() {
      return type_;
    }

    public static final int MESSAGE_FIELD_NUMBER = 2;
    private com.google.protobuf.ByteString message_;
    /**
     * <code>optional bytes message = 2;</code>
     * @return Whether the message field is set.
     */
    @java.lang.Override
    public boolean hasMessage() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional bytes message = 2;</code>
     * @return The message.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString getMessage() {
      return message_;
    }

    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, type_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeBytes(2, message_);
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(1, type_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(2, message_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.BitControl.CustomMessage)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.BitControl.CustomMessage other = (org.apache.drill.exec.proto.BitControl.CustomMessage) obj;

      if (hasType() != other.hasType()) return false;
      if (hasType()) {
        if (getType()
            != other.getType()) return false;
      }
      if (hasMessage() != other.hasMessage()) return false;
      if (hasMessage()) {
        if (!getMessage()
            .equals(other.getMessage())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasType()) {
        hash = (37 * hash) + TYPE_FIELD_NUMBER;
        hash = (53 * hash) + getType();
      }
      if (hasMessage()) {
        hash = (37 * hash) + MESSAGE_FIELD_NUMBER;
        hash = (53 * hash) + getMessage().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

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

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

      // Construct using org.apache.drill.exec.proto.BitControl.CustomMessage.newBuilder()
      private Builder() {

      }

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

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        type_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        message_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

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

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

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

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

      public Builder mergeFrom(org.apache.drill.exec.proto.BitControl.CustomMessage other) {
        if (other == org.apache.drill.exec.proto.BitControl.CustomMessage.getDefaultInstance()) return this;
        if (other.hasType()) {
          setType(other.getType());
        }
        if (other.hasMessage()) {
          setMessage(other.getMessage());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                type_ = input.readInt32();
                bitField0_ |= 0x00000001;
                break;
              } // case 8
              case 18: {
                message_ = input.readBytes();
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private int type_ ;
      /**
       * <code>optional int32 type = 1;</code>
       * @return Whether the type field is set.
       */
      @java.lang.Override
      public boolean hasType() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional int32 type = 1;</code>
       * @return The type.
       */
      @java.lang.Override
      public int getType() {
        return type_;
      }
      /**
       * <code>optional int32 type = 1;</code>
       * @param value The type to set.
       * @return This builder for chaining.
       */
      public Builder setType(int value) {
        bitField0_ |= 0x00000001;
        type_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 type = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearType() {
        bitField0_ = (bitField0_ & ~0x00000001);
        type_ = 0;
        onChanged();
        return this;
      }

      private com.google.protobuf.ByteString message_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>optional bytes message = 2;</code>
       * @return Whether the message field is set.
       */
      @java.lang.Override
      public boolean hasMessage() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional bytes message = 2;</code>
       * @return The message.
       */
      @java.lang.Override
      public com.google.protobuf.ByteString getMessage() {
        return message_;
      }
      /**
       * <code>optional bytes message = 2;</code>
       * @param value The message to set.
       * @return This builder for chaining.
       */
      public Builder setMessage(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        message_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bytes message = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearMessage() {
        bitField0_ = (bitField0_ & ~0x00000002);
        message_ = getDefaultInstance().getMessage();
        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.bit.control.CustomMessage)
    }

    // @@protoc_insertion_point(class_scope:exec.bit.control.CustomMessage)
    private static final org.apache.drill.exec.proto.BitControl.CustomMessage DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.BitControl.CustomMessage();
    }

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

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

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

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

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

  }

  public interface PlanFragmentOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.bit.control.PlanFragment)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional .exec.bit.FragmentHandle handle = 1;</code>
     * @return Whether the handle field is set.
     */
    boolean hasHandle();
    /**
     * <code>optional .exec.bit.FragmentHandle handle = 1;</code>
     * @return The handle.
     */
    org.apache.drill.exec.proto.ExecProtos.FragmentHandle getHandle();
    /**
     * <code>optional .exec.bit.FragmentHandle handle = 1;</code>
     */
    org.apache.drill.exec.proto.ExecProtos.FragmentHandleOrBuilder getHandleOrBuilder();

    /**
     * <code>optional float network_cost = 4;</code>
     * @return Whether the networkCost field is set.
     */
    boolean hasNetworkCost();
    /**
     * <code>optional float network_cost = 4;</code>
     * @return The networkCost.
     */
    float getNetworkCost();

    /**
     * <code>optional float cpu_cost = 5;</code>
     * @return Whether the cpuCost field is set.
     */
    boolean hasCpuCost();
    /**
     * <code>optional float cpu_cost = 5;</code>
     * @return The cpuCost.
     */
    float getCpuCost();

    /**
     * <code>optional float disk_cost = 6;</code>
     * @return Whether the diskCost field is set.
     */
    boolean hasDiskCost();
    /**
     * <code>optional float disk_cost = 6;</code>
     * @return The diskCost.
     */
    float getDiskCost();

    /**
     * <code>optional float memory_cost = 7;</code>
     * @return Whether the memoryCost field is set.
     */
    boolean hasMemoryCost();
    /**
     * <code>optional float memory_cost = 7;</code>
     * @return The memoryCost.
     */
    float getMemoryCost();

    /**
     * <code>optional string fragment_json = 8;</code>
     * @return Whether the fragmentJson field is set.
     */
    boolean hasFragmentJson();
    /**
     * <code>optional string fragment_json = 8;</code>
     * @return The fragmentJson.
     */
    java.lang.String getFragmentJson();
    /**
     * <code>optional string fragment_json = 8;</code>
     * @return The bytes for fragmentJson.
     */
    com.google.protobuf.ByteString
        getFragmentJsonBytes();

    /**
     * <code>optional bool leaf_fragment = 9;</code>
     * @return Whether the leafFragment field is set.
     */
    boolean hasLeafFragment();
    /**
     * <code>optional bool leaf_fragment = 9;</code>
     * @return The leafFragment.
     */
    boolean getLeafFragment();

    /**
     * <code>optional .exec.DrillbitEndpoint assignment = 10;</code>
     * @return Whether the assignment field is set.
     */
    boolean hasAssignment();
    /**
     * <code>optional .exec.DrillbitEndpoint assignment = 10;</code>
     * @return The assignment.
     */
    org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint getAssignment();
    /**
     * <code>optional .exec.DrillbitEndpoint assignment = 10;</code>
     */
    org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder getAssignmentOrBuilder();

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

    /**
     * <pre>
     * 20 megs
     * </pre>
     *
     * <code>optional int64 mem_initial = 12 [default = 20000000];</code>
     * @return Whether the memInitial field is set.
     */
    boolean hasMemInitial();
    /**
     * <pre>
     * 20 megs
     * </pre>
     *
     * <code>optional int64 mem_initial = 12 [default = 20000000];</code>
     * @return The memInitial.
     */
    long getMemInitial();

    /**
     * <pre>
     * 20 gigs
     * </pre>
     *
     * <code>optional int64 mem_max = 13 [default = 2000000000];</code>
     * @return Whether the memMax field is set.
     */
    boolean hasMemMax();
    /**
     * <pre>
     * 20 gigs
     * </pre>
     *
     * <code>optional int64 mem_max = 13 [default = 2000000000];</code>
     * @return The memMax.
     */
    long getMemMax();

    /**
     * <code>optional .exec.shared.UserCredentials credentials = 14;</code>
     * @return Whether the credentials field is set.
     */
    boolean hasCredentials();
    /**
     * <code>optional .exec.shared.UserCredentials credentials = 14;</code>
     * @return The credentials.
     */
    org.apache.drill.exec.proto.UserBitShared.UserCredentials getCredentials();
    /**
     * <code>optional .exec.shared.UserCredentials credentials = 14;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.UserCredentialsOrBuilder getCredentialsOrBuilder();

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

    /**
     * <code>optional .exec.bit.control.QueryContextInformation context = 16;</code>
     * @return Whether the context field is set.
     */
    boolean hasContext();
    /**
     * <code>optional .exec.bit.control.QueryContextInformation context = 16;</code>
     * @return The context.
     */
    org.apache.drill.exec.proto.BitControl.QueryContextInformation getContext();
    /**
     * <code>optional .exec.bit.control.QueryContextInformation context = 16;</code>
     */
    org.apache.drill.exec.proto.BitControl.QueryContextInformationOrBuilder getContextOrBuilder();

    /**
     * <code>repeated .exec.bit.control.Collector collector = 17;</code>
     */
    java.util.List<org.apache.drill.exec.proto.BitControl.Collector> 
        getCollectorList();
    /**
     * <code>repeated .exec.bit.control.Collector collector = 17;</code>
     */
    org.apache.drill.exec.proto.BitControl.Collector getCollector(int index);
    /**
     * <code>repeated .exec.bit.control.Collector collector = 17;</code>
     */
    int getCollectorCount();
    /**
     * <code>repeated .exec.bit.control.Collector collector = 17;</code>
     */
    java.util.List<? extends org.apache.drill.exec.proto.BitControl.CollectorOrBuilder> 
        getCollectorOrBuilderList();
    /**
     * <code>repeated .exec.bit.control.Collector collector = 17;</code>
     */
    org.apache.drill.exec.proto.BitControl.CollectorOrBuilder getCollectorOrBuilder(
        int index);
  }
  /**
   * Protobuf type {@code exec.bit.control.PlanFragment}
   */
  public static final class PlanFragment extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.bit.control.PlanFragment)
      PlanFragmentOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use PlanFragment.newBuilder() to construct.
    private PlanFragment(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private PlanFragment() {
      fragmentJson_ = "";
      memInitial_ = 20000000L;
      memMax_ = 2000000000L;
      optionsJson_ = "";
      collector_ = java.util.Collections.emptyList();
    }

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

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

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

    private int bitField0_;
    public static final int HANDLE_FIELD_NUMBER = 1;
    private org.apache.drill.exec.proto.ExecProtos.FragmentHandle handle_;
    /**
     * <code>optional .exec.bit.FragmentHandle handle = 1;</code>
     * @return Whether the handle field is set.
     */
    @java.lang.Override
    public boolean hasHandle() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional .exec.bit.FragmentHandle handle = 1;</code>
     * @return The handle.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.ExecProtos.FragmentHandle getHandle() {
      return handle_ == null ? org.apache.drill.exec.proto.ExecProtos.FragmentHandle.getDefaultInstance() : handle_;
    }
    /**
     * <code>optional .exec.bit.FragmentHandle handle = 1;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.ExecProtos.FragmentHandleOrBuilder getHandleOrBuilder() {
      return handle_ == null ? org.apache.drill.exec.proto.ExecProtos.FragmentHandle.getDefaultInstance() : handle_;
    }

    public static final int NETWORK_COST_FIELD_NUMBER = 4;
    private float networkCost_;
    /**
     * <code>optional float network_cost = 4;</code>
     * @return Whether the networkCost field is set.
     */
    @java.lang.Override
    public boolean hasNetworkCost() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional float network_cost = 4;</code>
     * @return The networkCost.
     */
    @java.lang.Override
    public float getNetworkCost() {
      return networkCost_;
    }

    public static final int CPU_COST_FIELD_NUMBER = 5;
    private float cpuCost_;
    /**
     * <code>optional float cpu_cost = 5;</code>
     * @return Whether the cpuCost field is set.
     */
    @java.lang.Override
    public boolean hasCpuCost() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional float cpu_cost = 5;</code>
     * @return The cpuCost.
     */
    @java.lang.Override
    public float getCpuCost() {
      return cpuCost_;
    }

    public static final int DISK_COST_FIELD_NUMBER = 6;
    private float diskCost_;
    /**
     * <code>optional float disk_cost = 6;</code>
     * @return Whether the diskCost field is set.
     */
    @java.lang.Override
    public boolean hasDiskCost() {
      return ((bitField0_ & 0x00000008) != 0);
    }
    /**
     * <code>optional float disk_cost = 6;</code>
     * @return The diskCost.
     */
    @java.lang.Override
    public float getDiskCost() {
      return diskCost_;
    }

    public static final int MEMORY_COST_FIELD_NUMBER = 7;
    private float memoryCost_;
    /**
     * <code>optional float memory_cost = 7;</code>
     * @return Whether the memoryCost field is set.
     */
    @java.lang.Override
    public boolean hasMemoryCost() {
      return ((bitField0_ & 0x00000010) != 0);
    }
    /**
     * <code>optional float memory_cost = 7;</code>
     * @return The memoryCost.
     */
    @java.lang.Override
    public float getMemoryCost() {
      return memoryCost_;
    }

    public static final int FRAGMENT_JSON_FIELD_NUMBER = 8;
    private volatile java.lang.Object fragmentJson_;
    /**
     * <code>optional string fragment_json = 8;</code>
     * @return Whether the fragmentJson field is set.
     */
    @java.lang.Override
    public boolean hasFragmentJson() {
      return ((bitField0_ & 0x00000020) != 0);
    }
    /**
     * <code>optional string fragment_json = 8;</code>
     * @return The fragmentJson.
     */
    @java.lang.Override
    public java.lang.String getFragmentJson() {
      java.lang.Object ref = fragmentJson_;
      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()) {
          fragmentJson_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string fragment_json = 8;</code>
     * @return The bytes for fragmentJson.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getFragmentJsonBytes() {
      java.lang.Object ref = fragmentJson_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        fragmentJson_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int LEAF_FRAGMENT_FIELD_NUMBER = 9;
    private boolean leafFragment_;
    /**
     * <code>optional bool leaf_fragment = 9;</code>
     * @return Whether the leafFragment field is set.
     */
    @java.lang.Override
    public boolean hasLeafFragment() {
      return ((bitField0_ & 0x00000040) != 0);
    }
    /**
     * <code>optional bool leaf_fragment = 9;</code>
     * @return The leafFragment.
     */
    @java.lang.Override
    public boolean getLeafFragment() {
      return leafFragment_;
    }

    public static final int ASSIGNMENT_FIELD_NUMBER = 10;
    private org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint assignment_;
    /**
     * <code>optional .exec.DrillbitEndpoint assignment = 10;</code>
     * @return Whether the assignment field is set.
     */
    @java.lang.Override
    public boolean hasAssignment() {
      return ((bitField0_ & 0x00000080) != 0);
    }
    /**
     * <code>optional .exec.DrillbitEndpoint assignment = 10;</code>
     * @return The assignment.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint getAssignment() {
      return assignment_ == null ? org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance() : assignment_;
    }
    /**
     * <code>optional .exec.DrillbitEndpoint assignment = 10;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder getAssignmentOrBuilder() {
      return assignment_ == null ? org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance() : assignment_;
    }

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

    public static final int MEM_INITIAL_FIELD_NUMBER = 12;
    private long memInitial_;
    /**
     * <pre>
     * 20 megs
     * </pre>
     *
     * <code>optional int64 mem_initial = 12 [default = 20000000];</code>
     * @return Whether the memInitial field is set.
     */
    @java.lang.Override
    public boolean hasMemInitial() {
      return ((bitField0_ & 0x00000200) != 0);
    }
    /**
     * <pre>
     * 20 megs
     * </pre>
     *
     * <code>optional int64 mem_initial = 12 [default = 20000000];</code>
     * @return The memInitial.
     */
    @java.lang.Override
    public long getMemInitial() {
      return memInitial_;
    }

    public static final int MEM_MAX_FIELD_NUMBER = 13;
    private long memMax_;
    /**
     * <pre>
     * 20 gigs
     * </pre>
     *
     * <code>optional int64 mem_max = 13 [default = 2000000000];</code>
     * @return Whether the memMax field is set.
     */
    @java.lang.Override
    public boolean hasMemMax() {
      return ((bitField0_ & 0x00000400) != 0);
    }
    /**
     * <pre>
     * 20 gigs
     * </pre>
     *
     * <code>optional int64 mem_max = 13 [default = 2000000000];</code>
     * @return The memMax.
     */
    @java.lang.Override
    public long getMemMax() {
      return memMax_;
    }

    public static final int CREDENTIALS_FIELD_NUMBER = 14;
    private org.apache.drill.exec.proto.UserBitShared.UserCredentials credentials_;
    /**
     * <code>optional .exec.shared.UserCredentials credentials = 14;</code>
     * @return Whether the credentials field is set.
     */
    @java.lang.Override
    public boolean hasCredentials() {
      return ((bitField0_ & 0x00000800) != 0);
    }
    /**
     * <code>optional .exec.shared.UserCredentials credentials = 14;</code>
     * @return The credentials.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.UserCredentials getCredentials() {
      return credentials_ == null ? org.apache.drill.exec.proto.UserBitShared.UserCredentials.getDefaultInstance() : credentials_;
    }
    /**
     * <code>optional .exec.shared.UserCredentials credentials = 14;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.UserCredentialsOrBuilder getCredentialsOrBuilder() {
      return credentials_ == null ? org.apache.drill.exec.proto.UserBitShared.UserCredentials.getDefaultInstance() : credentials_;
    }

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

    public static final int CONTEXT_FIELD_NUMBER = 16;
    private org.apache.drill.exec.proto.BitControl.QueryContextInformation context_;
    /**
     * <code>optional .exec.bit.control.QueryContextInformation context = 16;</code>
     * @return Whether the context field is set.
     */
    @java.lang.Override
    public boolean hasContext() {
      return ((bitField0_ & 0x00002000) != 0);
    }
    /**
     * <code>optional .exec.bit.control.QueryContextInformation context = 16;</code>
     * @return The context.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.BitControl.QueryContextInformation getContext() {
      return context_ == null ? org.apache.drill.exec.proto.BitControl.QueryContextInformation.getDefaultInstance() : context_;
    }
    /**
     * <code>optional .exec.bit.control.QueryContextInformation context = 16;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.BitControl.QueryContextInformationOrBuilder getContextOrBuilder() {
      return context_ == null ? org.apache.drill.exec.proto.BitControl.QueryContextInformation.getDefaultInstance() : context_;
    }

    public static final int COLLECTOR_FIELD_NUMBER = 17;
    private java.util.List<org.apache.drill.exec.proto.BitControl.Collector> collector_;
    /**
     * <code>repeated .exec.bit.control.Collector collector = 17;</code>
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.BitControl.Collector> getCollectorList() {
      return collector_;
    }
    /**
     * <code>repeated .exec.bit.control.Collector collector = 17;</code>
     */
    @java.lang.Override
    public java.util.List<? extends org.apache.drill.exec.proto.BitControl.CollectorOrBuilder> 
        getCollectorOrBuilderList() {
      return collector_;
    }
    /**
     * <code>repeated .exec.bit.control.Collector collector = 17;</code>
     */
    @java.lang.Override
    public int getCollectorCount() {
      return collector_.size();
    }
    /**
     * <code>repeated .exec.bit.control.Collector collector = 17;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.BitControl.Collector getCollector(int index) {
      return collector_.get(index);
    }
    /**
     * <code>repeated .exec.bit.control.Collector collector = 17;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.BitControl.CollectorOrBuilder getCollectorOrBuilder(
        int index) {
      return collector_.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.writeMessage(1, getHandle());
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeFloat(4, networkCost_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeFloat(5, cpuCost_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        output.writeFloat(6, diskCost_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        output.writeFloat(7, memoryCost_);
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 8, fragmentJson_);
      }
      if (((bitField0_ & 0x00000040) != 0)) {
        output.writeBool(9, leafFragment_);
      }
      if (((bitField0_ & 0x00000080) != 0)) {
        output.writeMessage(10, getAssignment());
      }
      if (((bitField0_ & 0x00000100) != 0)) {
        output.writeMessage(11, getForeman());
      }
      if (((bitField0_ & 0x00000200) != 0)) {
        output.writeInt64(12, memInitial_);
      }
      if (((bitField0_ & 0x00000400) != 0)) {
        output.writeInt64(13, memMax_);
      }
      if (((bitField0_ & 0x00000800) != 0)) {
        output.writeMessage(14, getCredentials());
      }
      if (((bitField0_ & 0x00001000) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 15, optionsJson_);
      }
      if (((bitField0_ & 0x00002000) != 0)) {
        output.writeMessage(16, getContext());
      }
      for (int i = 0; i < collector_.size(); i++) {
        output.writeMessage(17, collector_.get(i));
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, getHandle());
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeFloatSize(4, networkCost_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeFloatSize(5, cpuCost_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeFloatSize(6, diskCost_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeFloatSize(7, memoryCost_);
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(8, fragmentJson_);
      }
      if (((bitField0_ & 0x00000040) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(9, leafFragment_);
      }
      if (((bitField0_ & 0x00000080) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(10, getAssignment());
      }
      if (((bitField0_ & 0x00000100) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(11, getForeman());
      }
      if (((bitField0_ & 0x00000200) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(12, memInitial_);
      }
      if (((bitField0_ & 0x00000400) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(13, memMax_);
      }
      if (((bitField0_ & 0x00000800) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(14, getCredentials());
      }
      if (((bitField0_ & 0x00001000) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(15, optionsJson_);
      }
      if (((bitField0_ & 0x00002000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(16, getContext());
      }
      for (int i = 0; i < collector_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(17, collector_.get(i));
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.BitControl.PlanFragment)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.BitControl.PlanFragment other = (org.apache.drill.exec.proto.BitControl.PlanFragment) obj;

      if (hasHandle() != other.hasHandle()) return false;
      if (hasHandle()) {
        if (!getHandle()
            .equals(other.getHandle())) return false;
      }
      if (hasNetworkCost() != other.hasNetworkCost()) return false;
      if (hasNetworkCost()) {
        if (java.lang.Float.floatToIntBits(getNetworkCost())
            != java.lang.Float.floatToIntBits(
                other.getNetworkCost())) return false;
      }
      if (hasCpuCost() != other.hasCpuCost()) return false;
      if (hasCpuCost()) {
        if (java.lang.Float.floatToIntBits(getCpuCost())
            != java.lang.Float.floatToIntBits(
                other.getCpuCost())) return false;
      }
      if (hasDiskCost() != other.hasDiskCost()) return false;
      if (hasDiskCost()) {
        if (java.lang.Float.floatToIntBits(getDiskCost())
            != java.lang.Float.floatToIntBits(
                other.getDiskCost())) return false;
      }
      if (hasMemoryCost() != other.hasMemoryCost()) return false;
      if (hasMemoryCost()) {
        if (java.lang.Float.floatToIntBits(getMemoryCost())
            != java.lang.Float.floatToIntBits(
                other.getMemoryCost())) return false;
      }
      if (hasFragmentJson() != other.hasFragmentJson()) return false;
      if (hasFragmentJson()) {
        if (!getFragmentJson()
            .equals(other.getFragmentJson())) return false;
      }
      if (hasLeafFragment() != other.hasLeafFragment()) return false;
      if (hasLeafFragment()) {
        if (getLeafFragment()
            != other.getLeafFragment()) return false;
      }
      if (hasAssignment() != other.hasAssignment()) return false;
      if (hasAssignment()) {
        if (!getAssignment()
            .equals(other.getAssignment())) return false;
      }
      if (hasForeman() != other.hasForeman()) return false;
      if (hasForeman()) {
        if (!getForeman()
            .equals(other.getForeman())) return false;
      }
      if (hasMemInitial() != other.hasMemInitial()) return false;
      if (hasMemInitial()) {
        if (getMemInitial()
            != other.getMemInitial()) return false;
      }
      if (hasMemMax() != other.hasMemMax()) return false;
      if (hasMemMax()) {
        if (getMemMax()
            != other.getMemMax()) return false;
      }
      if (hasCredentials() != other.hasCredentials()) return false;
      if (hasCredentials()) {
        if (!getCredentials()
            .equals(other.getCredentials())) return false;
      }
      if (hasOptionsJson() != other.hasOptionsJson()) return false;
      if (hasOptionsJson()) {
        if (!getOptionsJson()
            .equals(other.getOptionsJson())) return false;
      }
      if (hasContext() != other.hasContext()) return false;
      if (hasContext()) {
        if (!getContext()
            .equals(other.getContext())) return false;
      }
      if (!getCollectorList()
          .equals(other.getCollectorList())) return false;
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasHandle()) {
        hash = (37 * hash) + HANDLE_FIELD_NUMBER;
        hash = (53 * hash) + getHandle().hashCode();
      }
      if (hasNetworkCost()) {
        hash = (37 * hash) + NETWORK_COST_FIELD_NUMBER;
        hash = (53 * hash) + java.lang.Float.floatToIntBits(
            getNetworkCost());
      }
      if (hasCpuCost()) {
        hash = (37 * hash) + CPU_COST_FIELD_NUMBER;
        hash = (53 * hash) + java.lang.Float.floatToIntBits(
            getCpuCost());
      }
      if (hasDiskCost()) {
        hash = (37 * hash) + DISK_COST_FIELD_NUMBER;
        hash = (53 * hash) + java.lang.Float.floatToIntBits(
            getDiskCost());
      }
      if (hasMemoryCost()) {
        hash = (37 * hash) + MEMORY_COST_FIELD_NUMBER;
        hash = (53 * hash) + java.lang.Float.floatToIntBits(
            getMemoryCost());
      }
      if (hasFragmentJson()) {
        hash = (37 * hash) + FRAGMENT_JSON_FIELD_NUMBER;
        hash = (53 * hash) + getFragmentJson().hashCode();
      }
      if (hasLeafFragment()) {
        hash = (37 * hash) + LEAF_FRAGMENT_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getLeafFragment());
      }
      if (hasAssignment()) {
        hash = (37 * hash) + ASSIGNMENT_FIELD_NUMBER;
        hash = (53 * hash) + getAssignment().hashCode();
      }
      if (hasForeman()) {
        hash = (37 * hash) + FOREMAN_FIELD_NUMBER;
        hash = (53 * hash) + getForeman().hashCode();
      }
      if (hasMemInitial()) {
        hash = (37 * hash) + MEM_INITIAL_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getMemInitial());
      }
      if (hasMemMax()) {
        hash = (37 * hash) + MEM_MAX_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getMemMax());
      }
      if (hasCredentials()) {
        hash = (37 * hash) + CREDENTIALS_FIELD_NUMBER;
        hash = (53 * hash) + getCredentials().hashCode();
      }
      if (hasOptionsJson()) {
        hash = (37 * hash) + OPTIONS_JSON_FIELD_NUMBER;
        hash = (53 * hash) + getOptionsJson().hashCode();
      }
      if (hasContext()) {
        hash = (37 * hash) + CONTEXT_FIELD_NUMBER;
        hash = (53 * hash) + getContext().hashCode();
      }
      if (getCollectorCount() > 0) {
        hash = (37 * hash) + COLLECTOR_FIELD_NUMBER;
        hash = (53 * hash) + getCollectorList().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

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

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

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

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getHandleFieldBuilder();
          getAssignmentFieldBuilder();
          getForemanFieldBuilder();
          getCredentialsFieldBuilder();
          getContextFieldBuilder();
          getCollectorFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        if (handleBuilder_ == null) {
          handle_ = null;
        } else {
          handleBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        networkCost_ = 0F;
        bitField0_ = (bitField0_ & ~0x00000002);
        cpuCost_ = 0F;
        bitField0_ = (bitField0_ & ~0x00000004);
        diskCost_ = 0F;
        bitField0_ = (bitField0_ & ~0x00000008);
        memoryCost_ = 0F;
        bitField0_ = (bitField0_ & ~0x00000010);
        fragmentJson_ = "";
        bitField0_ = (bitField0_ & ~0x00000020);
        leafFragment_ = false;
        bitField0_ = (bitField0_ & ~0x00000040);
        if (assignmentBuilder_ == null) {
          assignment_ = null;
        } else {
          assignmentBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000080);
        if (foremanBuilder_ == null) {
          foreman_ = null;
        } else {
          foremanBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000100);
        memInitial_ = 20000000L;
        bitField0_ = (bitField0_ & ~0x00000200);
        memMax_ = 2000000000L;
        bitField0_ = (bitField0_ & ~0x00000400);
        if (credentialsBuilder_ == null) {
          credentials_ = null;
        } else {
          credentialsBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000800);
        optionsJson_ = "";
        bitField0_ = (bitField0_ & ~0x00001000);
        if (contextBuilder_ == null) {
          context_ = null;
        } else {
          contextBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00002000);
        if (collectorBuilder_ == null) {
          collector_ = java.util.Collections.emptyList();
        } else {
          collector_ = null;
          collectorBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00004000);
        return this;
      }

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

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

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

      @java.lang.Override
      public org.apache.drill.exec.proto.BitControl.PlanFragment buildPartial() {
        org.apache.drill.exec.proto.BitControl.PlanFragment result = new org.apache.drill.exec.proto.BitControl.PlanFragment(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          if (handleBuilder_ == null) {
            result.handle_ = handle_;
          } else {
            result.handle_ = handleBuilder_.build();
          }
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.networkCost_ = networkCost_;
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.cpuCost_ = cpuCost_;
          to_bitField0_ |= 0x00000004;
        }
        if (((from_bitField0_ & 0x00000008) != 0)) {
          result.diskCost_ = diskCost_;
          to_bitField0_ |= 0x00000008;
        }
        if (((from_bitField0_ & 0x00000010) != 0)) {
          result.memoryCost_ = memoryCost_;
          to_bitField0_ |= 0x00000010;
        }
        if (((from_bitField0_ & 0x00000020) != 0)) {
          to_bitField0_ |= 0x00000020;
        }
        result.fragmentJson_ = fragmentJson_;
        if (((from_bitField0_ & 0x00000040) != 0)) {
          result.leafFragment_ = leafFragment_;
          to_bitField0_ |= 0x00000040;
        }
        if (((from_bitField0_ & 0x00000080) != 0)) {
          if (assignmentBuilder_ == null) {
            result.assignment_ = assignment_;
          } else {
            result.assignment_ = assignmentBuilder_.build();
          }
          to_bitField0_ |= 0x00000080;
        }
        if (((from_bitField0_ & 0x00000100) != 0)) {
          if (foremanBuilder_ == null) {
            result.foreman_ = foreman_;
          } else {
            result.foreman_ = foremanBuilder_.build();
          }
          to_bitField0_ |= 0x00000100;
        }
        if (((from_bitField0_ & 0x00000200) != 0)) {
          to_bitField0_ |= 0x00000200;
        }
        result.memInitial_ = memInitial_;
        if (((from_bitField0_ & 0x00000400) != 0)) {
          to_bitField0_ |= 0x00000400;
        }
        result.memMax_ = memMax_;
        if (((from_bitField0_ & 0x00000800) != 0)) {
          if (credentialsBuilder_ == null) {
            result.credentials_ = credentials_;
          } else {
            result.credentials_ = credentialsBuilder_.build();
          }
          to_bitField0_ |= 0x00000800;
        }
        if (((from_bitField0_ & 0x00001000) != 0)) {
          to_bitField0_ |= 0x00001000;
        }
        result.optionsJson_ = optionsJson_;
        if (((from_bitField0_ & 0x00002000) != 0)) {
          if (contextBuilder_ == null) {
            result.context_ = context_;
          } else {
            result.context_ = contextBuilder_.build();
          }
          to_bitField0_ |= 0x00002000;
        }
        if (collectorBuilder_ == null) {
          if (((bitField0_ & 0x00004000) != 0)) {
            collector_ = java.util.Collections.unmodifiableList(collector_);
            bitField0_ = (bitField0_ & ~0x00004000);
          }
          result.collector_ = collector_;
        } else {
          result.collector_ = collectorBuilder_.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.BitControl.PlanFragment) {
          return mergeFrom((org.apache.drill.exec.proto.BitControl.PlanFragment)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.BitControl.PlanFragment other) {
        if (other == org.apache.drill.exec.proto.BitControl.PlanFragment.getDefaultInstance()) return this;
        if (other.hasHandle()) {
          mergeHandle(other.getHandle());
        }
        if (other.hasNetworkCost()) {
          setNetworkCost(other.getNetworkCost());
        }
        if (other.hasCpuCost()) {
          setCpuCost(other.getCpuCost());
        }
        if (other.hasDiskCost()) {
          setDiskCost(other.getDiskCost());
        }
        if (other.hasMemoryCost()) {
          setMemoryCost(other.getMemoryCost());
        }
        if (other.hasFragmentJson()) {
          bitField0_ |= 0x00000020;
          fragmentJson_ = other.fragmentJson_;
          onChanged();
        }
        if (other.hasLeafFragment()) {
          setLeafFragment(other.getLeafFragment());
        }
        if (other.hasAssignment()) {
          mergeAssignment(other.getAssignment());
        }
        if (other.hasForeman()) {
          mergeForeman(other.getForeman());
        }
        if (other.hasMemInitial()) {
          setMemInitial(other.getMemInitial());
        }
        if (other.hasMemMax()) {
          setMemMax(other.getMemMax());
        }
        if (other.hasCredentials()) {
          mergeCredentials(other.getCredentials());
        }
        if (other.hasOptionsJson()) {
          bitField0_ |= 0x00001000;
          optionsJson_ = other.optionsJson_;
          onChanged();
        }
        if (other.hasContext()) {
          mergeContext(other.getContext());
        }
        if (collectorBuilder_ == null) {
          if (!other.collector_.isEmpty()) {
            if (collector_.isEmpty()) {
              collector_ = other.collector_;
              bitField0_ = (bitField0_ & ~0x00004000);
            } else {
              ensureCollectorIsMutable();
              collector_.addAll(other.collector_);
            }
            onChanged();
          }
        } else {
          if (!other.collector_.isEmpty()) {
            if (collectorBuilder_.isEmpty()) {
              collectorBuilder_.dispose();
              collectorBuilder_ = null;
              collector_ = other.collector_;
              bitField0_ = (bitField0_ & ~0x00004000);
              collectorBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getCollectorFieldBuilder() : null;
            } else {
              collectorBuilder_.addAllMessages(other.collector_);
            }
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                input.readMessage(
                    getHandleFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 37: {
                networkCost_ = input.readFloat();
                bitField0_ |= 0x00000002;
                break;
              } // case 37
              case 45: {
                cpuCost_ = input.readFloat();
                bitField0_ |= 0x00000004;
                break;
              } // case 45
              case 53: {
                diskCost_ = input.readFloat();
                bitField0_ |= 0x00000008;
                break;
              } // case 53
              case 61: {
                memoryCost_ = input.readFloat();
                bitField0_ |= 0x00000010;
                break;
              } // case 61
              case 66: {
                fragmentJson_ = input.readBytes();
                bitField0_ |= 0x00000020;
                break;
              } // case 66
              case 72: {
                leafFragment_ = input.readBool();
                bitField0_ |= 0x00000040;
                break;
              } // case 72
              case 82: {
                input.readMessage(
                    getAssignmentFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000080;
                break;
              } // case 82
              case 90: {
                input.readMessage(
                    getForemanFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000100;
                break;
              } // case 90
              case 96: {
                memInitial_ = input.readInt64();
                bitField0_ |= 0x00000200;
                break;
              } // case 96
              case 104: {
                memMax_ = input.readInt64();
                bitField0_ |= 0x00000400;
                break;
              } // case 104
              case 114: {
                input.readMessage(
                    getCredentialsFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000800;
                break;
              } // case 114
              case 122: {
                optionsJson_ = input.readBytes();
                bitField0_ |= 0x00001000;
                break;
              } // case 122
              case 130: {
                input.readMessage(
                    getContextFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00002000;
                break;
              } // case 130
              case 138: {
                org.apache.drill.exec.proto.BitControl.Collector m =
                    input.readMessage(
                        org.apache.drill.exec.proto.BitControl.Collector.PARSER,
                        extensionRegistry);
                if (collectorBuilder_ == null) {
                  ensureCollectorIsMutable();
                  collector_.add(m);
                } else {
                  collectorBuilder_.addMessage(m);
                }
                break;
              } // case 138
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private org.apache.drill.exec.proto.ExecProtos.FragmentHandle handle_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.ExecProtos.FragmentHandle, org.apache.drill.exec.proto.ExecProtos.FragmentHandle.Builder, org.apache.drill.exec.proto.ExecProtos.FragmentHandleOrBuilder> handleBuilder_;
      /**
       * <code>optional .exec.bit.FragmentHandle handle = 1;</code>
       * @return Whether the handle field is set.
       */
      public boolean hasHandle() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .exec.bit.FragmentHandle handle = 1;</code>
       * @return The handle.
       */
      public org.apache.drill.exec.proto.ExecProtos.FragmentHandle getHandle() {
        if (handleBuilder_ == null) {
          return handle_ == null ? org.apache.drill.exec.proto.ExecProtos.FragmentHandle.getDefaultInstance() : handle_;
        } else {
          return handleBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.bit.FragmentHandle handle = 1;</code>
       */
      public Builder setHandle(org.apache.drill.exec.proto.ExecProtos.FragmentHandle value) {
        if (handleBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          handle_ = value;
          onChanged();
        } else {
          handleBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.bit.FragmentHandle handle = 1;</code>
       */
      public Builder setHandle(
          org.apache.drill.exec.proto.ExecProtos.FragmentHandle.Builder builderForValue) {
        if (handleBuilder_ == null) {
          handle_ = builderForValue.build();
          onChanged();
        } else {
          handleBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.bit.FragmentHandle handle = 1;</code>
       */
      public Builder mergeHandle(org.apache.drill.exec.proto.ExecProtos.FragmentHandle value) {
        if (handleBuilder_ == null) {
          if (((bitField0_ & 0x00000001) != 0) &&
              handle_ != null &&
              handle_ != org.apache.drill.exec.proto.ExecProtos.FragmentHandle.getDefaultInstance()) {
            handle_ =
              org.apache.drill.exec.proto.ExecProtos.FragmentHandle.newBuilder(handle_).mergeFrom(value).buildPartial();
          } else {
            handle_ = value;
          }
          onChanged();
        } else {
          handleBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.bit.FragmentHandle handle = 1;</code>
       */
      public Builder clearHandle() {
        if (handleBuilder_ == null) {
          handle_ = null;
          onChanged();
        } else {
          handleBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>optional .exec.bit.FragmentHandle handle = 1;</code>
       */
      public org.apache.drill.exec.proto.ExecProtos.FragmentHandle.Builder getHandleBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getHandleFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.bit.FragmentHandle handle = 1;</code>
       */
      public org.apache.drill.exec.proto.ExecProtos.FragmentHandleOrBuilder getHandleOrBuilder() {
        if (handleBuilder_ != null) {
          return handleBuilder_.getMessageOrBuilder();
        } else {
          return handle_ == null ?
              org.apache.drill.exec.proto.ExecProtos.FragmentHandle.getDefaultInstance() : handle_;
        }
      }
      /**
       * <code>optional .exec.bit.FragmentHandle handle = 1;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.ExecProtos.FragmentHandle, org.apache.drill.exec.proto.ExecProtos.FragmentHandle.Builder, org.apache.drill.exec.proto.ExecProtos.FragmentHandleOrBuilder> 
          getHandleFieldBuilder() {
        if (handleBuilder_ == null) {
          handleBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.ExecProtos.FragmentHandle, org.apache.drill.exec.proto.ExecProtos.FragmentHandle.Builder, org.apache.drill.exec.proto.ExecProtos.FragmentHandleOrBuilder>(
                  getHandle(),
                  getParentForChildren(),
                  isClean());
          handle_ = null;
        }
        return handleBuilder_;
      }

      private float networkCost_ ;
      /**
       * <code>optional float network_cost = 4;</code>
       * @return Whether the networkCost field is set.
       */
      @java.lang.Override
      public boolean hasNetworkCost() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional float network_cost = 4;</code>
       * @return The networkCost.
       */
      @java.lang.Override
      public float getNetworkCost() {
        return networkCost_;
      }
      /**
       * <code>optional float network_cost = 4;</code>
       * @param value The networkCost to set.
       * @return This builder for chaining.
       */
      public Builder setNetworkCost(float value) {
        bitField0_ |= 0x00000002;
        networkCost_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional float network_cost = 4;</code>
       * @return This builder for chaining.
       */
      public Builder clearNetworkCost() {
        bitField0_ = (bitField0_ & ~0x00000002);
        networkCost_ = 0F;
        onChanged();
        return this;
      }

      private float cpuCost_ ;
      /**
       * <code>optional float cpu_cost = 5;</code>
       * @return Whether the cpuCost field is set.
       */
      @java.lang.Override
      public boolean hasCpuCost() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional float cpu_cost = 5;</code>
       * @return The cpuCost.
       */
      @java.lang.Override
      public float getCpuCost() {
        return cpuCost_;
      }
      /**
       * <code>optional float cpu_cost = 5;</code>
       * @param value The cpuCost to set.
       * @return This builder for chaining.
       */
      public Builder setCpuCost(float value) {
        bitField0_ |= 0x00000004;
        cpuCost_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional float cpu_cost = 5;</code>
       * @return This builder for chaining.
       */
      public Builder clearCpuCost() {
        bitField0_ = (bitField0_ & ~0x00000004);
        cpuCost_ = 0F;
        onChanged();
        return this;
      }

      private float diskCost_ ;
      /**
       * <code>optional float disk_cost = 6;</code>
       * @return Whether the diskCost field is set.
       */
      @java.lang.Override
      public boolean hasDiskCost() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <code>optional float disk_cost = 6;</code>
       * @return The diskCost.
       */
      @java.lang.Override
      public float getDiskCost() {
        return diskCost_;
      }
      /**
       * <code>optional float disk_cost = 6;</code>
       * @param value The diskCost to set.
       * @return This builder for chaining.
       */
      public Builder setDiskCost(float value) {
        bitField0_ |= 0x00000008;
        diskCost_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional float disk_cost = 6;</code>
       * @return This builder for chaining.
       */
      public Builder clearDiskCost() {
        bitField0_ = (bitField0_ & ~0x00000008);
        diskCost_ = 0F;
        onChanged();
        return this;
      }

      private float memoryCost_ ;
      /**
       * <code>optional float memory_cost = 7;</code>
       * @return Whether the memoryCost field is set.
       */
      @java.lang.Override
      public boolean hasMemoryCost() {
        return ((bitField0_ & 0x00000010) != 0);
      }
      /**
       * <code>optional float memory_cost = 7;</code>
       * @return The memoryCost.
       */
      @java.lang.Override
      public float getMemoryCost() {
        return memoryCost_;
      }
      /**
       * <code>optional float memory_cost = 7;</code>
       * @param value The memoryCost to set.
       * @return This builder for chaining.
       */
      public Builder setMemoryCost(float value) {
        bitField0_ |= 0x00000010;
        memoryCost_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional float memory_cost = 7;</code>
       * @return This builder for chaining.
       */
      public Builder clearMemoryCost() {
        bitField0_ = (bitField0_ & ~0x00000010);
        memoryCost_ = 0F;
        onChanged();
        return this;
      }

      private java.lang.Object fragmentJson_ = "";
      /**
       * <code>optional string fragment_json = 8;</code>
       * @return Whether the fragmentJson field is set.
       */
      public boolean hasFragmentJson() {
        return ((bitField0_ & 0x00000020) != 0);
      }
      /**
       * <code>optional string fragment_json = 8;</code>
       * @return The fragmentJson.
       */
      public java.lang.String getFragmentJson() {
        java.lang.Object ref = fragmentJson_;
        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()) {
            fragmentJson_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string fragment_json = 8;</code>
       * @return The bytes for fragmentJson.
       */
      public com.google.protobuf.ByteString
          getFragmentJsonBytes() {
        java.lang.Object ref = fragmentJson_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          fragmentJson_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string fragment_json = 8;</code>
       * @param value The fragmentJson to set.
       * @return This builder for chaining.
       */
      public Builder setFragmentJson(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000020;
        fragmentJson_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string fragment_json = 8;</code>
       * @return This builder for chaining.
       */
      public Builder clearFragmentJson() {
        bitField0_ = (bitField0_ & ~0x00000020);
        fragmentJson_ = getDefaultInstance().getFragmentJson();
        onChanged();
        return this;
      }
      /**
       * <code>optional string fragment_json = 8;</code>
       * @param value The bytes for fragmentJson to set.
       * @return This builder for chaining.
       */
      public Builder setFragmentJsonBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000020;
        fragmentJson_ = value;
        onChanged();
        return this;
      }

      private boolean leafFragment_ ;
      /**
       * <code>optional bool leaf_fragment = 9;</code>
       * @return Whether the leafFragment field is set.
       */
      @java.lang.Override
      public boolean hasLeafFragment() {
        return ((bitField0_ & 0x00000040) != 0);
      }
      /**
       * <code>optional bool leaf_fragment = 9;</code>
       * @return The leafFragment.
       */
      @java.lang.Override
      public boolean getLeafFragment() {
        return leafFragment_;
      }
      /**
       * <code>optional bool leaf_fragment = 9;</code>
       * @param value The leafFragment to set.
       * @return This builder for chaining.
       */
      public Builder setLeafFragment(boolean value) {
        bitField0_ |= 0x00000040;
        leafFragment_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool leaf_fragment = 9;</code>
       * @return This builder for chaining.
       */
      public Builder clearLeafFragment() {
        bitField0_ = (bitField0_ & ~0x00000040);
        leafFragment_ = false;
        onChanged();
        return this;
      }

      private org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint assignment_;
      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> assignmentBuilder_;
      /**
       * <code>optional .exec.DrillbitEndpoint assignment = 10;</code>
       * @return Whether the assignment field is set.
       */
      public boolean hasAssignment() {
        return ((bitField0_ & 0x00000080) != 0);
      }
      /**
       * <code>optional .exec.DrillbitEndpoint assignment = 10;</code>
       * @return The assignment.
       */
      public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint getAssignment() {
        if (assignmentBuilder_ == null) {
          return assignment_ == null ? org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance() : assignment_;
        } else {
          return assignmentBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.DrillbitEndpoint assignment = 10;</code>
       */
      public Builder setAssignment(org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint value) {
        if (assignmentBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          assignment_ = value;
          onChanged();
        } else {
          assignmentBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000080;
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint assignment = 10;</code>
       */
      public Builder setAssignment(
          org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder builderForValue) {
        if (assignmentBuilder_ == null) {
          assignment_ = builderForValue.build();
          onChanged();
        } else {
          assignmentBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000080;
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint assignment = 10;</code>
       */
      public Builder mergeAssignment(org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint value) {
        if (assignmentBuilder_ == null) {
          if (((bitField0_ & 0x00000080) != 0) &&
              assignment_ != null &&
              assignment_ != org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance()) {
            assignment_ =
              org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.newBuilder(assignment_).mergeFrom(value).buildPartial();
          } else {
            assignment_ = value;
          }
          onChanged();
        } else {
          assignmentBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000080;
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint assignment = 10;</code>
       */
      public Builder clearAssignment() {
        if (assignmentBuilder_ == null) {
          assignment_ = null;
          onChanged();
        } else {
          assignmentBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000080);
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint assignment = 10;</code>
       */
      public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder getAssignmentBuilder() {
        bitField0_ |= 0x00000080;
        onChanged();
        return getAssignmentFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.DrillbitEndpoint assignment = 10;</code>
       */
      public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpointOrBuilder getAssignmentOrBuilder() {
        if (assignmentBuilder_ != null) {
          return assignmentBuilder_.getMessageOrBuilder();
        } else {
          return assignment_ == null ?
              org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance() : assignment_;
        }
      }
      /**
       * <code>optional .exec.DrillbitEndpoint assignment = 10;</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> 
          getAssignmentFieldBuilder() {
        if (assignmentBuilder_ == null) {
          assignmentBuilder_ = 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>(
                  getAssignment(),
                  getParentForChildren(),
                  isClean());
          assignment_ = null;
        }
        return assignmentBuilder_;
      }

      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 = 11;</code>
       * @return Whether the foreman field is set.
       */
      public boolean hasForeman() {
        return ((bitField0_ & 0x00000100) != 0);
      }
      /**
       * <code>optional .exec.DrillbitEndpoint foreman = 11;</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 = 11;</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_ |= 0x00000100;
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint foreman = 11;</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_ |= 0x00000100;
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint foreman = 11;</code>
       */
      public Builder mergeForeman(org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint value) {
        if (foremanBuilder_ == null) {
          if (((bitField0_ & 0x00000100) != 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_ |= 0x00000100;
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint foreman = 11;</code>
       */
      public Builder clearForeman() {
        if (foremanBuilder_ == null) {
          foreman_ = null;
          onChanged();
        } else {
          foremanBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000100);
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint foreman = 11;</code>
       */
      public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder getForemanBuilder() {
        bitField0_ |= 0x00000100;
        onChanged();
        return getForemanFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.DrillbitEndpoint foreman = 11;</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 = 11;</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 long memInitial_ = 20000000L;
      /**
       * <pre>
       * 20 megs
       * </pre>
       *
       * <code>optional int64 mem_initial = 12 [default = 20000000];</code>
       * @return Whether the memInitial field is set.
       */
      @java.lang.Override
      public boolean hasMemInitial() {
        return ((bitField0_ & 0x00000200) != 0);
      }
      /**
       * <pre>
       * 20 megs
       * </pre>
       *
       * <code>optional int64 mem_initial = 12 [default = 20000000];</code>
       * @return The memInitial.
       */
      @java.lang.Override
      public long getMemInitial() {
        return memInitial_;
      }
      /**
       * <pre>
       * 20 megs
       * </pre>
       *
       * <code>optional int64 mem_initial = 12 [default = 20000000];</code>
       * @param value The memInitial to set.
       * @return This builder for chaining.
       */
      public Builder setMemInitial(long value) {
        bitField0_ |= 0x00000200;
        memInitial_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * 20 megs
       * </pre>
       *
       * <code>optional int64 mem_initial = 12 [default = 20000000];</code>
       * @return This builder for chaining.
       */
      public Builder clearMemInitial() {
        bitField0_ = (bitField0_ & ~0x00000200);
        memInitial_ = 20000000L;
        onChanged();
        return this;
      }

      private long memMax_ = 2000000000L;
      /**
       * <pre>
       * 20 gigs
       * </pre>
       *
       * <code>optional int64 mem_max = 13 [default = 2000000000];</code>
       * @return Whether the memMax field is set.
       */
      @java.lang.Override
      public boolean hasMemMax() {
        return ((bitField0_ & 0x00000400) != 0);
      }
      /**
       * <pre>
       * 20 gigs
       * </pre>
       *
       * <code>optional int64 mem_max = 13 [default = 2000000000];</code>
       * @return The memMax.
       */
      @java.lang.Override
      public long getMemMax() {
        return memMax_;
      }
      /**
       * <pre>
       * 20 gigs
       * </pre>
       *
       * <code>optional int64 mem_max = 13 [default = 2000000000];</code>
       * @param value The memMax to set.
       * @return This builder for chaining.
       */
      public Builder setMemMax(long value) {
        bitField0_ |= 0x00000400;
        memMax_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * 20 gigs
       * </pre>
       *
       * <code>optional int64 mem_max = 13 [default = 2000000000];</code>
       * @return This builder for chaining.
       */
      public Builder clearMemMax() {
        bitField0_ = (bitField0_ & ~0x00000400);
        memMax_ = 2000000000L;
        onChanged();
        return this;
      }

      private org.apache.drill.exec.proto.UserBitShared.UserCredentials credentials_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.UserCredentials, org.apache.drill.exec.proto.UserBitShared.UserCredentials.Builder, org.apache.drill.exec.proto.UserBitShared.UserCredentialsOrBuilder> credentialsBuilder_;
      /**
       * <code>optional .exec.shared.UserCredentials credentials = 14;</code>
       * @return Whether the credentials field is set.
       */
      public boolean hasCredentials() {
        return ((bitField0_ & 0x00000800) != 0);
      }
      /**
       * <code>optional .exec.shared.UserCredentials credentials = 14;</code>
       * @return The credentials.
       */
      public org.apache.drill.exec.proto.UserBitShared.UserCredentials getCredentials() {
        if (credentialsBuilder_ == null) {
          return credentials_ == null ? org.apache.drill.exec.proto.UserBitShared.UserCredentials.getDefaultInstance() : credentials_;
        } else {
          return credentialsBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.shared.UserCredentials credentials = 14;</code>
       */
      public Builder setCredentials(org.apache.drill.exec.proto.UserBitShared.UserCredentials value) {
        if (credentialsBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          credentials_ = value;
          onChanged();
        } else {
          credentialsBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000800;
        return this;
      }
      /**
       * <code>optional .exec.shared.UserCredentials credentials = 14;</code>
       */
      public Builder setCredentials(
          org.apache.drill.exec.proto.UserBitShared.UserCredentials.Builder builderForValue) {
        if (credentialsBuilder_ == null) {
          credentials_ = builderForValue.build();
          onChanged();
        } else {
          credentialsBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000800;
        return this;
      }
      /**
       * <code>optional .exec.shared.UserCredentials credentials = 14;</code>
       */
      public Builder mergeCredentials(org.apache.drill.exec.proto.UserBitShared.UserCredentials value) {
        if (credentialsBuilder_ == null) {
          if (((bitField0_ & 0x00000800) != 0) &&
              credentials_ != null &&
              credentials_ != org.apache.drill.exec.proto.UserBitShared.UserCredentials.getDefaultInstance()) {
            credentials_ =
              org.apache.drill.exec.proto.UserBitShared.UserCredentials.newBuilder(credentials_).mergeFrom(value).buildPartial();
          } else {
            credentials_ = value;
          }
          onChanged();
        } else {
          credentialsBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000800;
        return this;
      }
      /**
       * <code>optional .exec.shared.UserCredentials credentials = 14;</code>
       */
      public Builder clearCredentials() {
        if (credentialsBuilder_ == null) {
          credentials_ = null;
          onChanged();
        } else {
          credentialsBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000800);
        return this;
      }
      /**
       * <code>optional .exec.shared.UserCredentials credentials = 14;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.UserCredentials.Builder getCredentialsBuilder() {
        bitField0_ |= 0x00000800;
        onChanged();
        return getCredentialsFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.shared.UserCredentials credentials = 14;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.UserCredentialsOrBuilder getCredentialsOrBuilder() {
        if (credentialsBuilder_ != null) {
          return credentialsBuilder_.getMessageOrBuilder();
        } else {
          return credentials_ == null ?
              org.apache.drill.exec.proto.UserBitShared.UserCredentials.getDefaultInstance() : credentials_;
        }
      }
      /**
       * <code>optional .exec.shared.UserCredentials credentials = 14;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.UserCredentials, org.apache.drill.exec.proto.UserBitShared.UserCredentials.Builder, org.apache.drill.exec.proto.UserBitShared.UserCredentialsOrBuilder> 
          getCredentialsFieldBuilder() {
        if (credentialsBuilder_ == null) {
          credentialsBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.UserCredentials, org.apache.drill.exec.proto.UserBitShared.UserCredentials.Builder, org.apache.drill.exec.proto.UserBitShared.UserCredentialsOrBuilder>(
                  getCredentials(),
                  getParentForChildren(),
                  isClean());
          credentials_ = null;
        }
        return credentialsBuilder_;
      }

      private java.lang.Object optionsJson_ = "";
      /**
       * <code>optional string options_json = 15;</code>
       * @return Whether the optionsJson field is set.
       */
      public boolean hasOptionsJson() {
        return ((bitField0_ & 0x00001000) != 0);
      }
      /**
       * <code>optional string options_json = 15;</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 = 15;</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 = 15;</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_ |= 0x00001000;
        optionsJson_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string options_json = 15;</code>
       * @return This builder for chaining.
       */
      public Builder clearOptionsJson() {
        bitField0_ = (bitField0_ & ~0x00001000);
        optionsJson_ = getDefaultInstance().getOptionsJson();
        onChanged();
        return this;
      }
      /**
       * <code>optional string options_json = 15;</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_ |= 0x00001000;
        optionsJson_ = value;
        onChanged();
        return this;
      }

      private org.apache.drill.exec.proto.BitControl.QueryContextInformation context_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.BitControl.QueryContextInformation, org.apache.drill.exec.proto.BitControl.QueryContextInformation.Builder, org.apache.drill.exec.proto.BitControl.QueryContextInformationOrBuilder> contextBuilder_;
      /**
       * <code>optional .exec.bit.control.QueryContextInformation context = 16;</code>
       * @return Whether the context field is set.
       */
      public boolean hasContext() {
        return ((bitField0_ & 0x00002000) != 0);
      }
      /**
       * <code>optional .exec.bit.control.QueryContextInformation context = 16;</code>
       * @return The context.
       */
      public org.apache.drill.exec.proto.BitControl.QueryContextInformation getContext() {
        if (contextBuilder_ == null) {
          return context_ == null ? org.apache.drill.exec.proto.BitControl.QueryContextInformation.getDefaultInstance() : context_;
        } else {
          return contextBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.bit.control.QueryContextInformation context = 16;</code>
       */
      public Builder setContext(org.apache.drill.exec.proto.BitControl.QueryContextInformation value) {
        if (contextBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          context_ = value;
          onChanged();
        } else {
          contextBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00002000;
        return this;
      }
      /**
       * <code>optional .exec.bit.control.QueryContextInformation context = 16;</code>
       */
      public Builder setContext(
          org.apache.drill.exec.proto.BitControl.QueryContextInformation.Builder builderForValue) {
        if (contextBuilder_ == null) {
          context_ = builderForValue.build();
          onChanged();
        } else {
          contextBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00002000;
        return this;
      }
      /**
       * <code>optional .exec.bit.control.QueryContextInformation context = 16;</code>
       */
      public Builder mergeContext(org.apache.drill.exec.proto.BitControl.QueryContextInformation value) {
        if (contextBuilder_ == null) {
          if (((bitField0_ & 0x00002000) != 0) &&
              context_ != null &&
              context_ != org.apache.drill.exec.proto.BitControl.QueryContextInformation.getDefaultInstance()) {
            context_ =
              org.apache.drill.exec.proto.BitControl.QueryContextInformation.newBuilder(context_).mergeFrom(value).buildPartial();
          } else {
            context_ = value;
          }
          onChanged();
        } else {
          contextBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00002000;
        return this;
      }
      /**
       * <code>optional .exec.bit.control.QueryContextInformation context = 16;</code>
       */
      public Builder clearContext() {
        if (contextBuilder_ == null) {
          context_ = null;
          onChanged();
        } else {
          contextBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00002000);
        return this;
      }
      /**
       * <code>optional .exec.bit.control.QueryContextInformation context = 16;</code>
       */
      public org.apache.drill.exec.proto.BitControl.QueryContextInformation.Builder getContextBuilder() {
        bitField0_ |= 0x00002000;
        onChanged();
        return getContextFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.bit.control.QueryContextInformation context = 16;</code>
       */
      public org.apache.drill.exec.proto.BitControl.QueryContextInformationOrBuilder getContextOrBuilder() {
        if (contextBuilder_ != null) {
          return contextBuilder_.getMessageOrBuilder();
        } else {
          return context_ == null ?
              org.apache.drill.exec.proto.BitControl.QueryContextInformation.getDefaultInstance() : context_;
        }
      }
      /**
       * <code>optional .exec.bit.control.QueryContextInformation context = 16;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.BitControl.QueryContextInformation, org.apache.drill.exec.proto.BitControl.QueryContextInformation.Builder, org.apache.drill.exec.proto.BitControl.QueryContextInformationOrBuilder> 
          getContextFieldBuilder() {
        if (contextBuilder_ == null) {
          contextBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.BitControl.QueryContextInformation, org.apache.drill.exec.proto.BitControl.QueryContextInformation.Builder, org.apache.drill.exec.proto.BitControl.QueryContextInformationOrBuilder>(
                  getContext(),
                  getParentForChildren(),
                  isClean());
          context_ = null;
        }
        return contextBuilder_;
      }

      private java.util.List<org.apache.drill.exec.proto.BitControl.Collector> collector_ =
        java.util.Collections.emptyList();
      private void ensureCollectorIsMutable() {
        if (!((bitField0_ & 0x00004000) != 0)) {
          collector_ = new java.util.ArrayList<org.apache.drill.exec.proto.BitControl.Collector>(collector_);
          bitField0_ |= 0x00004000;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.BitControl.Collector, org.apache.drill.exec.proto.BitControl.Collector.Builder, org.apache.drill.exec.proto.BitControl.CollectorOrBuilder> collectorBuilder_;

      /**
       * <code>repeated .exec.bit.control.Collector collector = 17;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.BitControl.Collector> getCollectorList() {
        if (collectorBuilder_ == null) {
          return java.util.Collections.unmodifiableList(collector_);
        } else {
          return collectorBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .exec.bit.control.Collector collector = 17;</code>
       */
      public int getCollectorCount() {
        if (collectorBuilder_ == null) {
          return collector_.size();
        } else {
          return collectorBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .exec.bit.control.Collector collector = 17;</code>
       */
      public org.apache.drill.exec.proto.BitControl.Collector getCollector(int index) {
        if (collectorBuilder_ == null) {
          return collector_.get(index);
        } else {
          return collectorBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .exec.bit.control.Collector collector = 17;</code>
       */
      public Builder setCollector(
          int index, org.apache.drill.exec.proto.BitControl.Collector value) {
        if (collectorBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureCollectorIsMutable();
          collector_.set(index, value);
          onChanged();
        } else {
          collectorBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.Collector collector = 17;</code>
       */
      public Builder setCollector(
          int index, org.apache.drill.exec.proto.BitControl.Collector.Builder builderForValue) {
        if (collectorBuilder_ == null) {
          ensureCollectorIsMutable();
          collector_.set(index, builderForValue.build());
          onChanged();
        } else {
          collectorBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.Collector collector = 17;</code>
       */
      public Builder addCollector(org.apache.drill.exec.proto.BitControl.Collector value) {
        if (collectorBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureCollectorIsMutable();
          collector_.add(value);
          onChanged();
        } else {
          collectorBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.Collector collector = 17;</code>
       */
      public Builder addCollector(
          int index, org.apache.drill.exec.proto.BitControl.Collector value) {
        if (collectorBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureCollectorIsMutable();
          collector_.add(index, value);
          onChanged();
        } else {
          collectorBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.Collector collector = 17;</code>
       */
      public Builder addCollector(
          org.apache.drill.exec.proto.BitControl.Collector.Builder builderForValue) {
        if (collectorBuilder_ == null) {
          ensureCollectorIsMutable();
          collector_.add(builderForValue.build());
          onChanged();
        } else {
          collectorBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.Collector collector = 17;</code>
       */
      public Builder addCollector(
          int index, org.apache.drill.exec.proto.BitControl.Collector.Builder builderForValue) {
        if (collectorBuilder_ == null) {
          ensureCollectorIsMutable();
          collector_.add(index, builderForValue.build());
          onChanged();
        } else {
          collectorBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.Collector collector = 17;</code>
       */
      public Builder addAllCollector(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.BitControl.Collector> values) {
        if (collectorBuilder_ == null) {
          ensureCollectorIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, collector_);
          onChanged();
        } else {
          collectorBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.Collector collector = 17;</code>
       */
      public Builder clearCollector() {
        if (collectorBuilder_ == null) {
          collector_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00004000);
          onChanged();
        } else {
          collectorBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.Collector collector = 17;</code>
       */
      public Builder removeCollector(int index) {
        if (collectorBuilder_ == null) {
          ensureCollectorIsMutable();
          collector_.remove(index);
          onChanged();
        } else {
          collectorBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.Collector collector = 17;</code>
       */
      public org.apache.drill.exec.proto.BitControl.Collector.Builder getCollectorBuilder(
          int index) {
        return getCollectorFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .exec.bit.control.Collector collector = 17;</code>
       */
      public org.apache.drill.exec.proto.BitControl.CollectorOrBuilder getCollectorOrBuilder(
          int index) {
        if (collectorBuilder_ == null) {
          return collector_.get(index);  } else {
          return collectorBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .exec.bit.control.Collector collector = 17;</code>
       */
      public java.util.List<? extends org.apache.drill.exec.proto.BitControl.CollectorOrBuilder> 
           getCollectorOrBuilderList() {
        if (collectorBuilder_ != null) {
          return collectorBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(collector_);
        }
      }
      /**
       * <code>repeated .exec.bit.control.Collector collector = 17;</code>
       */
      public org.apache.drill.exec.proto.BitControl.Collector.Builder addCollectorBuilder() {
        return getCollectorFieldBuilder().addBuilder(
            org.apache.drill.exec.proto.BitControl.Collector.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.bit.control.Collector collector = 17;</code>
       */
      public org.apache.drill.exec.proto.BitControl.Collector.Builder addCollectorBuilder(
          int index) {
        return getCollectorFieldBuilder().addBuilder(
            index, org.apache.drill.exec.proto.BitControl.Collector.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.bit.control.Collector collector = 17;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.BitControl.Collector.Builder> 
           getCollectorBuilderList() {
        return getCollectorFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.BitControl.Collector, org.apache.drill.exec.proto.BitControl.Collector.Builder, org.apache.drill.exec.proto.BitControl.CollectorOrBuilder> 
          getCollectorFieldBuilder() {
        if (collectorBuilder_ == null) {
          collectorBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              org.apache.drill.exec.proto.BitControl.Collector, org.apache.drill.exec.proto.BitControl.Collector.Builder, org.apache.drill.exec.proto.BitControl.CollectorOrBuilder>(
                  collector_,
                  ((bitField0_ & 0x00004000) != 0),
                  getParentForChildren(),
                  isClean());
          collector_ = null;
        }
        return collectorBuilder_;
      }
      @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.bit.control.PlanFragment)
    }

    // @@protoc_insertion_point(class_scope:exec.bit.control.PlanFragment)
    private static final org.apache.drill.exec.proto.BitControl.PlanFragment DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.BitControl.PlanFragment();
    }

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

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

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

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

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

  }

  public interface CollectorOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.bit.control.Collector)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional int32 opposite_major_fragment_id = 1;</code>
     * @return Whether the oppositeMajorFragmentId field is set.
     */
    boolean hasOppositeMajorFragmentId();
    /**
     * <code>optional int32 opposite_major_fragment_id = 1;</code>
     * @return The oppositeMajorFragmentId.
     */
    int getOppositeMajorFragmentId();

    /**
     * <code>repeated int32 incoming_minor_fragment = 2 [packed = true];</code>
     * @return A list containing the incomingMinorFragment.
     */
    java.util.List<java.lang.Integer> getIncomingMinorFragmentList();
    /**
     * <code>repeated int32 incoming_minor_fragment = 2 [packed = true];</code>
     * @return The count of incomingMinorFragment.
     */
    int getIncomingMinorFragmentCount();
    /**
     * <code>repeated int32 incoming_minor_fragment = 2 [packed = true];</code>
     * @param index The index of the element to return.
     * @return The incomingMinorFragment at the given index.
     */
    int getIncomingMinorFragment(int index);

    /**
     * <code>optional bool supports_out_of_order = 3;</code>
     * @return Whether the supportsOutOfOrder field is set.
     */
    boolean hasSupportsOutOfOrder();
    /**
     * <code>optional bool supports_out_of_order = 3;</code>
     * @return The supportsOutOfOrder.
     */
    boolean getSupportsOutOfOrder();

    /**
     * <code>optional bool is_spooling = 4;</code>
     * @return Whether the isSpooling field is set.
     */
    boolean hasIsSpooling();
    /**
     * <code>optional bool is_spooling = 4;</code>
     * @return The isSpooling.
     */
    boolean getIsSpooling();

    /**
     * <code>optional bool enable_dynamic_fc = 5;</code>
     * @return Whether the enableDynamicFc field is set.
     */
    boolean hasEnableDynamicFc();
    /**
     * <code>optional bool enable_dynamic_fc = 5;</code>
     * @return The enableDynamicFc.
     */
    boolean getEnableDynamicFc();
  }
  /**
   * Protobuf type {@code exec.bit.control.Collector}
   */
  public static final class Collector extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.bit.control.Collector)
      CollectorOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use Collector.newBuilder() to construct.
    private Collector(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private Collector() {
      incomingMinorFragment_ = emptyIntList();
    }

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

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

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

    private int bitField0_;
    public static final int OPPOSITE_MAJOR_FRAGMENT_ID_FIELD_NUMBER = 1;
    private int oppositeMajorFragmentId_;
    /**
     * <code>optional int32 opposite_major_fragment_id = 1;</code>
     * @return Whether the oppositeMajorFragmentId field is set.
     */
    @java.lang.Override
    public boolean hasOppositeMajorFragmentId() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional int32 opposite_major_fragment_id = 1;</code>
     * @return The oppositeMajorFragmentId.
     */
    @java.lang.Override
    public int getOppositeMajorFragmentId() {
      return oppositeMajorFragmentId_;
    }

    public static final int INCOMING_MINOR_FRAGMENT_FIELD_NUMBER = 2;
    private com.google.protobuf.Internal.IntList incomingMinorFragment_;
    /**
     * <code>repeated int32 incoming_minor_fragment = 2 [packed = true];</code>
     * @return A list containing the incomingMinorFragment.
     */
    @java.lang.Override
    public java.util.List<java.lang.Integer>
        getIncomingMinorFragmentList() {
      return incomingMinorFragment_;
    }
    /**
     * <code>repeated int32 incoming_minor_fragment = 2 [packed = true];</code>
     * @return The count of incomingMinorFragment.
     */
    public int getIncomingMinorFragmentCount() {
      return incomingMinorFragment_.size();
    }
    /**
     * <code>repeated int32 incoming_minor_fragment = 2 [packed = true];</code>
     * @param index The index of the element to return.
     * @return The incomingMinorFragment at the given index.
     */
    public int getIncomingMinorFragment(int index) {
      return incomingMinorFragment_.getInt(index);
    }
    private int incomingMinorFragmentMemoizedSerializedSize = -1;

    public static final int SUPPORTS_OUT_OF_ORDER_FIELD_NUMBER = 3;
    private boolean supportsOutOfOrder_;
    /**
     * <code>optional bool supports_out_of_order = 3;</code>
     * @return Whether the supportsOutOfOrder field is set.
     */
    @java.lang.Override
    public boolean hasSupportsOutOfOrder() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional bool supports_out_of_order = 3;</code>
     * @return The supportsOutOfOrder.
     */
    @java.lang.Override
    public boolean getSupportsOutOfOrder() {
      return supportsOutOfOrder_;
    }

    public static final int IS_SPOOLING_FIELD_NUMBER = 4;
    private boolean isSpooling_;
    /**
     * <code>optional bool is_spooling = 4;</code>
     * @return Whether the isSpooling field is set.
     */
    @java.lang.Override
    public boolean hasIsSpooling() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional bool is_spooling = 4;</code>
     * @return The isSpooling.
     */
    @java.lang.Override
    public boolean getIsSpooling() {
      return isSpooling_;
    }

    public static final int ENABLE_DYNAMIC_FC_FIELD_NUMBER = 5;
    private boolean enableDynamicFc_;
    /**
     * <code>optional bool enable_dynamic_fc = 5;</code>
     * @return Whether the enableDynamicFc field is set.
     */
    @java.lang.Override
    public boolean hasEnableDynamicFc() {
      return ((bitField0_ & 0x00000008) != 0);
    }
    /**
     * <code>optional bool enable_dynamic_fc = 5;</code>
     * @return The enableDynamicFc.
     */
    @java.lang.Override
    public boolean getEnableDynamicFc() {
      return enableDynamicFc_;
    }

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

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeInt32(1, oppositeMajorFragmentId_);
      }
      if (getIncomingMinorFragmentList().size() > 0) {
        output.writeUInt32NoTag(18);
        output.writeUInt32NoTag(incomingMinorFragmentMemoizedSerializedSize);
      }
      for (int i = 0; i < incomingMinorFragment_.size(); i++) {
        output.writeInt32NoTag(incomingMinorFragment_.getInt(i));
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeBool(3, supportsOutOfOrder_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeBool(4, isSpooling_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        output.writeBool(5, enableDynamicFc_);
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(1, oppositeMajorFragmentId_);
      }
      {
        int dataSize = 0;
        for (int i = 0; i < incomingMinorFragment_.size(); i++) {
          dataSize += com.google.protobuf.CodedOutputStream
            .computeInt32SizeNoTag(incomingMinorFragment_.getInt(i));
        }
        size += dataSize;
        if (!getIncomingMinorFragmentList().isEmpty()) {
          size += 1;
          size += com.google.protobuf.CodedOutputStream
              .computeInt32SizeNoTag(dataSize);
        }
        incomingMinorFragmentMemoizedSerializedSize = dataSize;
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(3, supportsOutOfOrder_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(4, isSpooling_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(5, enableDynamicFc_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.BitControl.Collector)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.BitControl.Collector other = (org.apache.drill.exec.proto.BitControl.Collector) obj;

      if (hasOppositeMajorFragmentId() != other.hasOppositeMajorFragmentId()) return false;
      if (hasOppositeMajorFragmentId()) {
        if (getOppositeMajorFragmentId()
            != other.getOppositeMajorFragmentId()) return false;
      }
      if (!getIncomingMinorFragmentList()
          .equals(other.getIncomingMinorFragmentList())) return false;
      if (hasSupportsOutOfOrder() != other.hasSupportsOutOfOrder()) return false;
      if (hasSupportsOutOfOrder()) {
        if (getSupportsOutOfOrder()
            != other.getSupportsOutOfOrder()) return false;
      }
      if (hasIsSpooling() != other.hasIsSpooling()) return false;
      if (hasIsSpooling()) {
        if (getIsSpooling()
            != other.getIsSpooling()) return false;
      }
      if (hasEnableDynamicFc() != other.hasEnableDynamicFc()) return false;
      if (hasEnableDynamicFc()) {
        if (getEnableDynamicFc()
            != other.getEnableDynamicFc()) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasOppositeMajorFragmentId()) {
        hash = (37 * hash) + OPPOSITE_MAJOR_FRAGMENT_ID_FIELD_NUMBER;
        hash = (53 * hash) + getOppositeMajorFragmentId();
      }
      if (getIncomingMinorFragmentCount() > 0) {
        hash = (37 * hash) + INCOMING_MINOR_FRAGMENT_FIELD_NUMBER;
        hash = (53 * hash) + getIncomingMinorFragmentList().hashCode();
      }
      if (hasSupportsOutOfOrder()) {
        hash = (37 * hash) + SUPPORTS_OUT_OF_ORDER_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getSupportsOutOfOrder());
      }
      if (hasIsSpooling()) {
        hash = (37 * hash) + IS_SPOOLING_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getIsSpooling());
      }
      if (hasEnableDynamicFc()) {
        hash = (37 * hash) + ENABLE_DYNAMIC_FC_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getEnableDynamicFc());
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

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

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

      // Construct using org.apache.drill.exec.proto.BitControl.Collector.newBuilder()
      private Builder() {

      }

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

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        oppositeMajorFragmentId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        incomingMinorFragment_ = emptyIntList();
        bitField0_ = (bitField0_ & ~0x00000002);
        supportsOutOfOrder_ = false;
        bitField0_ = (bitField0_ & ~0x00000004);
        isSpooling_ = false;
        bitField0_ = (bitField0_ & ~0x00000008);
        enableDynamicFc_ = false;
        bitField0_ = (bitField0_ & ~0x00000010);
        return this;
      }

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

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

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

      @java.lang.Override
      public org.apache.drill.exec.proto.BitControl.Collector buildPartial() {
        org.apache.drill.exec.proto.BitControl.Collector result = new org.apache.drill.exec.proto.BitControl.Collector(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.oppositeMajorFragmentId_ = oppositeMajorFragmentId_;
          to_bitField0_ |= 0x00000001;
        }
        if (((bitField0_ & 0x00000002) != 0)) {
          incomingMinorFragment_.makeImmutable();
          bitField0_ = (bitField0_ & ~0x00000002);
        }
        result.incomingMinorFragment_ = incomingMinorFragment_;
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.supportsOutOfOrder_ = supportsOutOfOrder_;
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000008) != 0)) {
          result.isSpooling_ = isSpooling_;
          to_bitField0_ |= 0x00000004;
        }
        if (((from_bitField0_ & 0x00000010) != 0)) {
          result.enableDynamicFc_ = enableDynamicFc_;
          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.BitControl.Collector) {
          return mergeFrom((org.apache.drill.exec.proto.BitControl.Collector)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.BitControl.Collector other) {
        if (other == org.apache.drill.exec.proto.BitControl.Collector.getDefaultInstance()) return this;
        if (other.hasOppositeMajorFragmentId()) {
          setOppositeMajorFragmentId(other.getOppositeMajorFragmentId());
        }
        if (!other.incomingMinorFragment_.isEmpty()) {
          if (incomingMinorFragment_.isEmpty()) {
            incomingMinorFragment_ = other.incomingMinorFragment_;
            bitField0_ = (bitField0_ & ~0x00000002);
          } else {
            ensureIncomingMinorFragmentIsMutable();
            incomingMinorFragment_.addAll(other.incomingMinorFragment_);
          }
          onChanged();
        }
        if (other.hasSupportsOutOfOrder()) {
          setSupportsOutOfOrder(other.getSupportsOutOfOrder());
        }
        if (other.hasIsSpooling()) {
          setIsSpooling(other.getIsSpooling());
        }
        if (other.hasEnableDynamicFc()) {
          setEnableDynamicFc(other.getEnableDynamicFc());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                oppositeMajorFragmentId_ = input.readInt32();
                bitField0_ |= 0x00000001;
                break;
              } // case 8
              case 16: {
                int v = input.readInt32();
                ensureIncomingMinorFragmentIsMutable();
                incomingMinorFragment_.addInt(v);
                break;
              } // case 16
              case 18: {
                int length = input.readRawVarint32();
                int limit = input.pushLimit(length);
                ensureIncomingMinorFragmentIsMutable();
                while (input.getBytesUntilLimit() > 0) {
                  incomingMinorFragment_.addInt(input.readInt32());
                }
                input.popLimit(limit);
                break;
              } // case 18
              case 24: {
                supportsOutOfOrder_ = input.readBool();
                bitField0_ |= 0x00000004;
                break;
              } // case 24
              case 32: {
                isSpooling_ = input.readBool();
                bitField0_ |= 0x00000008;
                break;
              } // case 32
              case 40: {
                enableDynamicFc_ = input.readBool();
                bitField0_ |= 0x00000010;
                break;
              } // case 40
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private int oppositeMajorFragmentId_ ;
      /**
       * <code>optional int32 opposite_major_fragment_id = 1;</code>
       * @return Whether the oppositeMajorFragmentId field is set.
       */
      @java.lang.Override
      public boolean hasOppositeMajorFragmentId() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional int32 opposite_major_fragment_id = 1;</code>
       * @return The oppositeMajorFragmentId.
       */
      @java.lang.Override
      public int getOppositeMajorFragmentId() {
        return oppositeMajorFragmentId_;
      }
      /**
       * <code>optional int32 opposite_major_fragment_id = 1;</code>
       * @param value The oppositeMajorFragmentId to set.
       * @return This builder for chaining.
       */
      public Builder setOppositeMajorFragmentId(int value) {
        bitField0_ |= 0x00000001;
        oppositeMajorFragmentId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 opposite_major_fragment_id = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearOppositeMajorFragmentId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        oppositeMajorFragmentId_ = 0;
        onChanged();
        return this;
      }

      private com.google.protobuf.Internal.IntList incomingMinorFragment_ = emptyIntList();
      private void ensureIncomingMinorFragmentIsMutable() {
        if (!((bitField0_ & 0x00000002) != 0)) {
          incomingMinorFragment_ = mutableCopy(incomingMinorFragment_);
          bitField0_ |= 0x00000002;
         }
      }
      /**
       * <code>repeated int32 incoming_minor_fragment = 2 [packed = true];</code>
       * @return A list containing the incomingMinorFragment.
       */
      public java.util.List<java.lang.Integer>
          getIncomingMinorFragmentList() {
        return ((bitField0_ & 0x00000002) != 0) ?
                 java.util.Collections.unmodifiableList(incomingMinorFragment_) : incomingMinorFragment_;
      }
      /**
       * <code>repeated int32 incoming_minor_fragment = 2 [packed = true];</code>
       * @return The count of incomingMinorFragment.
       */
      public int getIncomingMinorFragmentCount() {
        return incomingMinorFragment_.size();
      }
      /**
       * <code>repeated int32 incoming_minor_fragment = 2 [packed = true];</code>
       * @param index The index of the element to return.
       * @return The incomingMinorFragment at the given index.
       */
      public int getIncomingMinorFragment(int index) {
        return incomingMinorFragment_.getInt(index);
      }
      /**
       * <code>repeated int32 incoming_minor_fragment = 2 [packed = true];</code>
       * @param index The index to set the value at.
       * @param value The incomingMinorFragment to set.
       * @return This builder for chaining.
       */
      public Builder setIncomingMinorFragment(
          int index, int value) {
        ensureIncomingMinorFragmentIsMutable();
        incomingMinorFragment_.setInt(index, value);
        onChanged();
        return this;
      }
      /**
       * <code>repeated int32 incoming_minor_fragment = 2 [packed = true];</code>
       * @param value The incomingMinorFragment to add.
       * @return This builder for chaining.
       */
      public Builder addIncomingMinorFragment(int value) {
        ensureIncomingMinorFragmentIsMutable();
        incomingMinorFragment_.addInt(value);
        onChanged();
        return this;
      }
      /**
       * <code>repeated int32 incoming_minor_fragment = 2 [packed = true];</code>
       * @param values The incomingMinorFragment to add.
       * @return This builder for chaining.
       */
      public Builder addAllIncomingMinorFragment(
          java.lang.Iterable<? extends java.lang.Integer> values) {
        ensureIncomingMinorFragmentIsMutable();
        com.google.protobuf.AbstractMessageLite.Builder.addAll(
            values, incomingMinorFragment_);
        onChanged();
        return this;
      }
      /**
       * <code>repeated int32 incoming_minor_fragment = 2 [packed = true];</code>
       * @return This builder for chaining.
       */
      public Builder clearIncomingMinorFragment() {
        incomingMinorFragment_ = emptyIntList();
        bitField0_ = (bitField0_ & ~0x00000002);
        onChanged();
        return this;
      }

      private boolean supportsOutOfOrder_ ;
      /**
       * <code>optional bool supports_out_of_order = 3;</code>
       * @return Whether the supportsOutOfOrder field is set.
       */
      @java.lang.Override
      public boolean hasSupportsOutOfOrder() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional bool supports_out_of_order = 3;</code>
       * @return The supportsOutOfOrder.
       */
      @java.lang.Override
      public boolean getSupportsOutOfOrder() {
        return supportsOutOfOrder_;
      }
      /**
       * <code>optional bool supports_out_of_order = 3;</code>
       * @param value The supportsOutOfOrder to set.
       * @return This builder for chaining.
       */
      public Builder setSupportsOutOfOrder(boolean value) {
        bitField0_ |= 0x00000004;
        supportsOutOfOrder_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool supports_out_of_order = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearSupportsOutOfOrder() {
        bitField0_ = (bitField0_ & ~0x00000004);
        supportsOutOfOrder_ = false;
        onChanged();
        return this;
      }

      private boolean isSpooling_ ;
      /**
       * <code>optional bool is_spooling = 4;</code>
       * @return Whether the isSpooling field is set.
       */
      @java.lang.Override
      public boolean hasIsSpooling() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <code>optional bool is_spooling = 4;</code>
       * @return The isSpooling.
       */
      @java.lang.Override
      public boolean getIsSpooling() {
        return isSpooling_;
      }
      /**
       * <code>optional bool is_spooling = 4;</code>
       * @param value The isSpooling to set.
       * @return This builder for chaining.
       */
      public Builder setIsSpooling(boolean value) {
        bitField0_ |= 0x00000008;
        isSpooling_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool is_spooling = 4;</code>
       * @return This builder for chaining.
       */
      public Builder clearIsSpooling() {
        bitField0_ = (bitField0_ & ~0x00000008);
        isSpooling_ = false;
        onChanged();
        return this;
      }

      private boolean enableDynamicFc_ ;
      /**
       * <code>optional bool enable_dynamic_fc = 5;</code>
       * @return Whether the enableDynamicFc field is set.
       */
      @java.lang.Override
      public boolean hasEnableDynamicFc() {
        return ((bitField0_ & 0x00000010) != 0);
      }
      /**
       * <code>optional bool enable_dynamic_fc = 5;</code>
       * @return The enableDynamicFc.
       */
      @java.lang.Override
      public boolean getEnableDynamicFc() {
        return enableDynamicFc_;
      }
      /**
       * <code>optional bool enable_dynamic_fc = 5;</code>
       * @param value The enableDynamicFc to set.
       * @return This builder for chaining.
       */
      public Builder setEnableDynamicFc(boolean value) {
        bitField0_ |= 0x00000010;
        enableDynamicFc_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool enable_dynamic_fc = 5;</code>
       * @return This builder for chaining.
       */
      public Builder clearEnableDynamicFc() {
        bitField0_ = (bitField0_ & ~0x00000010);
        enableDynamicFc_ = 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.bit.control.Collector)
    }

    // @@protoc_insertion_point(class_scope:exec.bit.control.Collector)
    private static final org.apache.drill.exec.proto.BitControl.Collector DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.BitControl.Collector();
    }

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

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

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

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

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

  }

  public interface QueryContextInformationOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.bit.control.QueryContextInformation)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <pre>
     * start time of query in milliseconds
     * </pre>
     *
     * <code>optional int64 query_start_time = 1;</code>
     * @return Whether the queryStartTime field is set.
     */
    boolean hasQueryStartTime();
    /**
     * <pre>
     * start time of query in milliseconds
     * </pre>
     *
     * <code>optional int64 query_start_time = 1;</code>
     * @return The queryStartTime.
     */
    long getQueryStartTime();

    /**
     * <pre>
     * timezone of the Drillbit where user is connected
     * </pre>
     *
     * <code>optional int32 time_zone = 2;</code>
     * @return Whether the timeZone field is set.
     */
    boolean hasTimeZone();
    /**
     * <pre>
     * timezone of the Drillbit where user is connected
     * </pre>
     *
     * <code>optional int32 time_zone = 2;</code>
     * @return The timeZone.
     */
    int getTimeZone();

    /**
     * <pre>
     * default schema in current session when the query is submitted
     * </pre>
     *
     * <code>optional string default_schema_name = 3;</code>
     * @return Whether the defaultSchemaName field is set.
     */
    boolean hasDefaultSchemaName();
    /**
     * <pre>
     * default schema in current session when the query is submitted
     * </pre>
     *
     * <code>optional string default_schema_name = 3;</code>
     * @return The defaultSchemaName.
     */
    java.lang.String getDefaultSchemaName();
    /**
     * <pre>
     * default schema in current session when the query is submitted
     * </pre>
     *
     * <code>optional string default_schema_name = 3;</code>
     * @return The bytes for defaultSchemaName.
     */
    com.google.protobuf.ByteString
        getDefaultSchemaNameBytes();

    /**
     * <pre>
     * current session id
     * </pre>
     *
     * <code>optional string session_id = 4;</code>
     * @return Whether the sessionId field is set.
     */
    boolean hasSessionId();
    /**
     * <pre>
     * current session id
     * </pre>
     *
     * <code>optional string session_id = 4;</code>
     * @return The sessionId.
     */
    java.lang.String getSessionId();
    /**
     * <pre>
     * current session id
     * </pre>
     *
     * <code>optional string session_id = 4;</code>
     * @return The bytes for sessionId.
     */
    com.google.protobuf.ByteString
        getSessionIdBytes();
  }
  /**
   * Protobuf type {@code exec.bit.control.QueryContextInformation}
   */
  public static final class QueryContextInformation extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.bit.control.QueryContextInformation)
      QueryContextInformationOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use QueryContextInformation.newBuilder() to construct.
    private QueryContextInformation(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private QueryContextInformation() {
      defaultSchemaName_ = "";
      sessionId_ = "";
    }

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

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

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

    private int bitField0_;
    public static final int QUERY_START_TIME_FIELD_NUMBER = 1;
    private long queryStartTime_;
    /**
     * <pre>
     * start time of query in milliseconds
     * </pre>
     *
     * <code>optional int64 query_start_time = 1;</code>
     * @return Whether the queryStartTime field is set.
     */
    @java.lang.Override
    public boolean hasQueryStartTime() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <pre>
     * start time of query in milliseconds
     * </pre>
     *
     * <code>optional int64 query_start_time = 1;</code>
     * @return The queryStartTime.
     */
    @java.lang.Override
    public long getQueryStartTime() {
      return queryStartTime_;
    }

    public static final int TIME_ZONE_FIELD_NUMBER = 2;
    private int timeZone_;
    /**
     * <pre>
     * timezone of the Drillbit where user is connected
     * </pre>
     *
     * <code>optional int32 time_zone = 2;</code>
     * @return Whether the timeZone field is set.
     */
    @java.lang.Override
    public boolean hasTimeZone() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <pre>
     * timezone of the Drillbit where user is connected
     * </pre>
     *
     * <code>optional int32 time_zone = 2;</code>
     * @return The timeZone.
     */
    @java.lang.Override
    public int getTimeZone() {
      return timeZone_;
    }

    public static final int DEFAULT_SCHEMA_NAME_FIELD_NUMBER = 3;
    private volatile java.lang.Object defaultSchemaName_;
    /**
     * <pre>
     * default schema in current session when the query is submitted
     * </pre>
     *
     * <code>optional string default_schema_name = 3;</code>
     * @return Whether the defaultSchemaName field is set.
     */
    @java.lang.Override
    public boolean hasDefaultSchemaName() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <pre>
     * default schema in current session when the query is submitted
     * </pre>
     *
     * <code>optional string default_schema_name = 3;</code>
     * @return The defaultSchemaName.
     */
    @java.lang.Override
    public java.lang.String getDefaultSchemaName() {
      java.lang.Object ref = defaultSchemaName_;
      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()) {
          defaultSchemaName_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * default schema in current session when the query is submitted
     * </pre>
     *
     * <code>optional string default_schema_name = 3;</code>
     * @return The bytes for defaultSchemaName.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getDefaultSchemaNameBytes() {
      java.lang.Object ref = defaultSchemaName_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        defaultSchemaName_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int SESSION_ID_FIELD_NUMBER = 4;
    private volatile java.lang.Object sessionId_;
    /**
     * <pre>
     * current session id
     * </pre>
     *
     * <code>optional string session_id = 4;</code>
     * @return Whether the sessionId field is set.
     */
    @java.lang.Override
    public boolean hasSessionId() {
      return ((bitField0_ & 0x00000008) != 0);
    }
    /**
     * <pre>
     * current session id
     * </pre>
     *
     * <code>optional string session_id = 4;</code>
     * @return The sessionId.
     */
    @java.lang.Override
    public java.lang.String getSessionId() {
      java.lang.Object ref = sessionId_;
      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()) {
          sessionId_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * current session id
     * </pre>
     *
     * <code>optional string session_id = 4;</code>
     * @return The bytes for sessionId.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getSessionIdBytes() {
      java.lang.Object ref = sessionId_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        sessionId_ = 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)) {
        output.writeInt64(1, queryStartTime_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeInt32(2, timeZone_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 3, defaultSchemaName_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 4, sessionId_);
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(1, queryStartTime_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(2, timeZone_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, defaultSchemaName_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, sessionId_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.BitControl.QueryContextInformation)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.BitControl.QueryContextInformation other = (org.apache.drill.exec.proto.BitControl.QueryContextInformation) obj;

      if (hasQueryStartTime() != other.hasQueryStartTime()) return false;
      if (hasQueryStartTime()) {
        if (getQueryStartTime()
            != other.getQueryStartTime()) return false;
      }
      if (hasTimeZone() != other.hasTimeZone()) return false;
      if (hasTimeZone()) {
        if (getTimeZone()
            != other.getTimeZone()) return false;
      }
      if (hasDefaultSchemaName() != other.hasDefaultSchemaName()) return false;
      if (hasDefaultSchemaName()) {
        if (!getDefaultSchemaName()
            .equals(other.getDefaultSchemaName())) return false;
      }
      if (hasSessionId() != other.hasSessionId()) return false;
      if (hasSessionId()) {
        if (!getSessionId()
            .equals(other.getSessionId())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasQueryStartTime()) {
        hash = (37 * hash) + QUERY_START_TIME_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getQueryStartTime());
      }
      if (hasTimeZone()) {
        hash = (37 * hash) + TIME_ZONE_FIELD_NUMBER;
        hash = (53 * hash) + getTimeZone();
      }
      if (hasDefaultSchemaName()) {
        hash = (37 * hash) + DEFAULT_SCHEMA_NAME_FIELD_NUMBER;
        hash = (53 * hash) + getDefaultSchemaName().hashCode();
      }
      if (hasSessionId()) {
        hash = (37 * hash) + SESSION_ID_FIELD_NUMBER;
        hash = (53 * hash) + getSessionId().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

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

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

      // Construct using org.apache.drill.exec.proto.BitControl.QueryContextInformation.newBuilder()
      private Builder() {

      }

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

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        queryStartTime_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000001);
        timeZone_ = 0;
        bitField0_ = (bitField0_ & ~0x00000002);
        defaultSchemaName_ = "";
        bitField0_ = (bitField0_ & ~0x00000004);
        sessionId_ = "";
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }

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

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

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

      @java.lang.Override
      public org.apache.drill.exec.proto.BitControl.QueryContextInformation buildPartial() {
        org.apache.drill.exec.proto.BitControl.QueryContextInformation result = new org.apache.drill.exec.proto.BitControl.QueryContextInformation(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.queryStartTime_ = queryStartTime_;
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.timeZone_ = timeZone_;
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          to_bitField0_ |= 0x00000004;
        }
        result.defaultSchemaName_ = defaultSchemaName_;
        if (((from_bitField0_ & 0x00000008) != 0)) {
          to_bitField0_ |= 0x00000008;
        }
        result.sessionId_ = sessionId_;
        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.BitControl.QueryContextInformation) {
          return mergeFrom((org.apache.drill.exec.proto.BitControl.QueryContextInformation)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.BitControl.QueryContextInformation other) {
        if (other == org.apache.drill.exec.proto.BitControl.QueryContextInformation.getDefaultInstance()) return this;
        if (other.hasQueryStartTime()) {
          setQueryStartTime(other.getQueryStartTime());
        }
        if (other.hasTimeZone()) {
          setTimeZone(other.getTimeZone());
        }
        if (other.hasDefaultSchemaName()) {
          bitField0_ |= 0x00000004;
          defaultSchemaName_ = other.defaultSchemaName_;
          onChanged();
        }
        if (other.hasSessionId()) {
          bitField0_ |= 0x00000008;
          sessionId_ = other.sessionId_;
          onChanged();
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                queryStartTime_ = input.readInt64();
                bitField0_ |= 0x00000001;
                break;
              } // case 8
              case 16: {
                timeZone_ = input.readInt32();
                bitField0_ |= 0x00000002;
                break;
              } // case 16
              case 26: {
                defaultSchemaName_ = input.readBytes();
                bitField0_ |= 0x00000004;
                break;
              } // case 26
              case 34: {
                sessionId_ = input.readBytes();
                bitField0_ |= 0x00000008;
                break;
              } // case 34
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private long queryStartTime_ ;
      /**
       * <pre>
       * start time of query in milliseconds
       * </pre>
       *
       * <code>optional int64 query_start_time = 1;</code>
       * @return Whether the queryStartTime field is set.
       */
      @java.lang.Override
      public boolean hasQueryStartTime() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <pre>
       * start time of query in milliseconds
       * </pre>
       *
       * <code>optional int64 query_start_time = 1;</code>
       * @return The queryStartTime.
       */
      @java.lang.Override
      public long getQueryStartTime() {
        return queryStartTime_;
      }
      /**
       * <pre>
       * start time of query in milliseconds
       * </pre>
       *
       * <code>optional int64 query_start_time = 1;</code>
       * @param value The queryStartTime to set.
       * @return This builder for chaining.
       */
      public Builder setQueryStartTime(long value) {
        bitField0_ |= 0x00000001;
        queryStartTime_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * start time of query in milliseconds
       * </pre>
       *
       * <code>optional int64 query_start_time = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearQueryStartTime() {
        bitField0_ = (bitField0_ & ~0x00000001);
        queryStartTime_ = 0L;
        onChanged();
        return this;
      }

      private int timeZone_ ;
      /**
       * <pre>
       * timezone of the Drillbit where user is connected
       * </pre>
       *
       * <code>optional int32 time_zone = 2;</code>
       * @return Whether the timeZone field is set.
       */
      @java.lang.Override
      public boolean hasTimeZone() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <pre>
       * timezone of the Drillbit where user is connected
       * </pre>
       *
       * <code>optional int32 time_zone = 2;</code>
       * @return The timeZone.
       */
      @java.lang.Override
      public int getTimeZone() {
        return timeZone_;
      }
      /**
       * <pre>
       * timezone of the Drillbit where user is connected
       * </pre>
       *
       * <code>optional int32 time_zone = 2;</code>
       * @param value The timeZone to set.
       * @return This builder for chaining.
       */
      public Builder setTimeZone(int value) {
        bitField0_ |= 0x00000002;
        timeZone_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * timezone of the Drillbit where user is connected
       * </pre>
       *
       * <code>optional int32 time_zone = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearTimeZone() {
        bitField0_ = (bitField0_ & ~0x00000002);
        timeZone_ = 0;
        onChanged();
        return this;
      }

      private java.lang.Object defaultSchemaName_ = "";
      /**
       * <pre>
       * default schema in current session when the query is submitted
       * </pre>
       *
       * <code>optional string default_schema_name = 3;</code>
       * @return Whether the defaultSchemaName field is set.
       */
      public boolean hasDefaultSchemaName() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <pre>
       * default schema in current session when the query is submitted
       * </pre>
       *
       * <code>optional string default_schema_name = 3;</code>
       * @return The defaultSchemaName.
       */
      public java.lang.String getDefaultSchemaName() {
        java.lang.Object ref = defaultSchemaName_;
        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()) {
            defaultSchemaName_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * default schema in current session when the query is submitted
       * </pre>
       *
       * <code>optional string default_schema_name = 3;</code>
       * @return The bytes for defaultSchemaName.
       */
      public com.google.protobuf.ByteString
          getDefaultSchemaNameBytes() {
        java.lang.Object ref = defaultSchemaName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          defaultSchemaName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * default schema in current session when the query is submitted
       * </pre>
       *
       * <code>optional string default_schema_name = 3;</code>
       * @param value The defaultSchemaName to set.
       * @return This builder for chaining.
       */
      public Builder setDefaultSchemaName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        defaultSchemaName_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * default schema in current session when the query is submitted
       * </pre>
       *
       * <code>optional string default_schema_name = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearDefaultSchemaName() {
        bitField0_ = (bitField0_ & ~0x00000004);
        defaultSchemaName_ = getDefaultInstance().getDefaultSchemaName();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * default schema in current session when the query is submitted
       * </pre>
       *
       * <code>optional string default_schema_name = 3;</code>
       * @param value The bytes for defaultSchemaName to set.
       * @return This builder for chaining.
       */
      public Builder setDefaultSchemaNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        defaultSchemaName_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object sessionId_ = "";
      /**
       * <pre>
       * current session id
       * </pre>
       *
       * <code>optional string session_id = 4;</code>
       * @return Whether the sessionId field is set.
       */
      public boolean hasSessionId() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <pre>
       * current session id
       * </pre>
       *
       * <code>optional string session_id = 4;</code>
       * @return The sessionId.
       */
      public java.lang.String getSessionId() {
        java.lang.Object ref = sessionId_;
        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()) {
            sessionId_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * current session id
       * </pre>
       *
       * <code>optional string session_id = 4;</code>
       * @return The bytes for sessionId.
       */
      public com.google.protobuf.ByteString
          getSessionIdBytes() {
        java.lang.Object ref = sessionId_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          sessionId_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * current session id
       * </pre>
       *
       * <code>optional string session_id = 4;</code>
       * @param value The sessionId to set.
       * @return This builder for chaining.
       */
      public Builder setSessionId(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        sessionId_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * current session id
       * </pre>
       *
       * <code>optional string session_id = 4;</code>
       * @return This builder for chaining.
       */
      public Builder clearSessionId() {
        bitField0_ = (bitField0_ & ~0x00000008);
        sessionId_ = getDefaultInstance().getSessionId();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * current session id
       * </pre>
       *
       * <code>optional string session_id = 4;</code>
       * @param value The bytes for sessionId to set.
       * @return This builder for chaining.
       */
      public Builder setSessionIdBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        sessionId_ = 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.bit.control.QueryContextInformation)
    }

    // @@protoc_insertion_point(class_scope:exec.bit.control.QueryContextInformation)
    private static final org.apache.drill.exec.proto.BitControl.QueryContextInformation DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.BitControl.QueryContextInformation();
    }

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

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

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

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

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

  }

  public interface WorkQueueStatusOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.bit.control.WorkQueueStatus)
      com.google.protobuf.MessageOrBuilder {

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

    /**
     * <code>optional int32 queue_length = 2;</code>
     * @return Whether the queueLength field is set.
     */
    boolean hasQueueLength();
    /**
     * <code>optional int32 queue_length = 2;</code>
     * @return The queueLength.
     */
    int getQueueLength();

    /**
     * <code>optional int64 report_time = 3;</code>
     * @return Whether the reportTime field is set.
     */
    boolean hasReportTime();
    /**
     * <code>optional int64 report_time = 3;</code>
     * @return The reportTime.
     */
    long getReportTime();
  }
  /**
   * Protobuf type {@code exec.bit.control.WorkQueueStatus}
   */
  public static final class WorkQueueStatus extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.bit.control.WorkQueueStatus)
      WorkQueueStatusOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use WorkQueueStatus.newBuilder() to construct.
    private WorkQueueStatus(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private WorkQueueStatus() {
    }

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

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

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

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

    public static final int QUEUE_LENGTH_FIELD_NUMBER = 2;
    private int queueLength_;
    /**
     * <code>optional int32 queue_length = 2;</code>
     * @return Whether the queueLength field is set.
     */
    @java.lang.Override
    public boolean hasQueueLength() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional int32 queue_length = 2;</code>
     * @return The queueLength.
     */
    @java.lang.Override
    public int getQueueLength() {
      return queueLength_;
    }

    public static final int REPORT_TIME_FIELD_NUMBER = 3;
    private long reportTime_;
    /**
     * <code>optional int64 report_time = 3;</code>
     * @return Whether the reportTime field is set.
     */
    @java.lang.Override
    public boolean hasReportTime() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional int64 report_time = 3;</code>
     * @return The reportTime.
     */
    @java.lang.Override
    public long getReportTime() {
      return reportTime_;
    }

    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, getEndpoint());
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeInt32(2, queueLength_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeInt64(3, reportTime_);
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, getEndpoint());
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(2, queueLength_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(3, reportTime_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.BitControl.WorkQueueStatus)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.BitControl.WorkQueueStatus other = (org.apache.drill.exec.proto.BitControl.WorkQueueStatus) obj;

      if (hasEndpoint() != other.hasEndpoint()) return false;
      if (hasEndpoint()) {
        if (!getEndpoint()
            .equals(other.getEndpoint())) return false;
      }
      if (hasQueueLength() != other.hasQueueLength()) return false;
      if (hasQueueLength()) {
        if (getQueueLength()
            != other.getQueueLength()) return false;
      }
      if (hasReportTime() != other.hasReportTime()) return false;
      if (hasReportTime()) {
        if (getReportTime()
            != other.getReportTime()) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasEndpoint()) {
        hash = (37 * hash) + ENDPOINT_FIELD_NUMBER;
        hash = (53 * hash) + getEndpoint().hashCode();
      }
      if (hasQueueLength()) {
        hash = (37 * hash) + QUEUE_LENGTH_FIELD_NUMBER;
        hash = (53 * hash) + getQueueLength();
      }
      if (hasReportTime()) {
        hash = (37 * hash) + REPORT_TIME_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getReportTime());
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

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

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

      // Construct using org.apache.drill.exec.proto.BitControl.WorkQueueStatus.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();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        if (endpointBuilder_ == null) {
          endpoint_ = null;
        } else {
          endpointBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        queueLength_ = 0;
        bitField0_ = (bitField0_ & ~0x00000002);
        reportTime_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

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

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

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

      @java.lang.Override
      public org.apache.drill.exec.proto.BitControl.WorkQueueStatus buildPartial() {
        org.apache.drill.exec.proto.BitControl.WorkQueueStatus result = new org.apache.drill.exec.proto.BitControl.WorkQueueStatus(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          if (endpointBuilder_ == null) {
            result.endpoint_ = endpoint_;
          } else {
            result.endpoint_ = endpointBuilder_.build();
          }
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.queueLength_ = queueLength_;
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.reportTime_ = reportTime_;
          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.BitControl.WorkQueueStatus) {
          return mergeFrom((org.apache.drill.exec.proto.BitControl.WorkQueueStatus)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.BitControl.WorkQueueStatus other) {
        if (other == org.apache.drill.exec.proto.BitControl.WorkQueueStatus.getDefaultInstance()) return this;
        if (other.hasEndpoint()) {
          mergeEndpoint(other.getEndpoint());
        }
        if (other.hasQueueLength()) {
          setQueueLength(other.getQueueLength());
        }
        if (other.hasReportTime()) {
          setReportTime(other.getReportTime());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                input.readMessage(
                    getEndpointFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 16: {
                queueLength_ = input.readInt32();
                bitField0_ |= 0x00000002;
                break;
              } // case 16
              case 24: {
                reportTime_ = input.readInt64();
                bitField0_ |= 0x00000004;
                break;
              } // case 24
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private 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 = 1;</code>
       * @return Whether the endpoint field is set.
       */
      public boolean hasEndpoint() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 1;</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 = 1;</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_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 1;</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_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 1;</code>
       */
      public Builder mergeEndpoint(org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint value) {
        if (endpointBuilder_ == null) {
          if (((bitField0_ & 0x00000001) != 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_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 1;</code>
       */
      public Builder clearEndpoint() {
        if (endpointBuilder_ == null) {
          endpoint_ = null;
          onChanged();
        } else {
          endpointBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 1;</code>
       */
      public org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.Builder getEndpointBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getEndpointFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.DrillbitEndpoint endpoint = 1;</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 = 1;</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 queueLength_ ;
      /**
       * <code>optional int32 queue_length = 2;</code>
       * @return Whether the queueLength field is set.
       */
      @java.lang.Override
      public boolean hasQueueLength() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional int32 queue_length = 2;</code>
       * @return The queueLength.
       */
      @java.lang.Override
      public int getQueueLength() {
        return queueLength_;
      }
      /**
       * <code>optional int32 queue_length = 2;</code>
       * @param value The queueLength to set.
       * @return This builder for chaining.
       */
      public Builder setQueueLength(int value) {
        bitField0_ |= 0x00000002;
        queueLength_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 queue_length = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearQueueLength() {
        bitField0_ = (bitField0_ & ~0x00000002);
        queueLength_ = 0;
        onChanged();
        return this;
      }

      private long reportTime_ ;
      /**
       * <code>optional int64 report_time = 3;</code>
       * @return Whether the reportTime field is set.
       */
      @java.lang.Override
      public boolean hasReportTime() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional int64 report_time = 3;</code>
       * @return The reportTime.
       */
      @java.lang.Override
      public long getReportTime() {
        return reportTime_;
      }
      /**
       * <code>optional int64 report_time = 3;</code>
       * @param value The reportTime to set.
       * @return This builder for chaining.
       */
      public Builder setReportTime(long value) {
        bitField0_ |= 0x00000004;
        reportTime_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int64 report_time = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearReportTime() {
        bitField0_ = (bitField0_ & ~0x00000004);
        reportTime_ = 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.bit.control.WorkQueueStatus)
    }

    // @@protoc_insertion_point(class_scope:exec.bit.control.WorkQueueStatus)
    private static final org.apache.drill.exec.proto.BitControl.WorkQueueStatus DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.BitControl.WorkQueueStatus();
    }

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

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

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

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

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

  }

  public interface FinishedReceiverOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.bit.control.FinishedReceiver)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional .exec.bit.FragmentHandle receiver = 1;</code>
     * @return Whether the receiver field is set.
     */
    boolean hasReceiver();
    /**
     * <code>optional .exec.bit.FragmentHandle receiver = 1;</code>
     * @return The receiver.
     */
    org.apache.drill.exec.proto.ExecProtos.FragmentHandle getReceiver();
    /**
     * <code>optional .exec.bit.FragmentHandle receiver = 1;</code>
     */
    org.apache.drill.exec.proto.ExecProtos.FragmentHandleOrBuilder getReceiverOrBuilder();

    /**
     * <code>optional .exec.bit.FragmentHandle sender = 2;</code>
     * @return Whether the sender field is set.
     */
    boolean hasSender();
    /**
     * <code>optional .exec.bit.FragmentHandle sender = 2;</code>
     * @return The sender.
     */
    org.apache.drill.exec.proto.ExecProtos.FragmentHandle getSender();
    /**
     * <code>optional .exec.bit.FragmentHandle sender = 2;</code>
     */
    org.apache.drill.exec.proto.ExecProtos.FragmentHandleOrBuilder getSenderOrBuilder();
  }
  /**
   * Protobuf type {@code exec.bit.control.FinishedReceiver}
   */
  public static final class FinishedReceiver extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.bit.control.FinishedReceiver)
      FinishedReceiverOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use FinishedReceiver.newBuilder() to construct.
    private FinishedReceiver(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private FinishedReceiver() {
    }

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

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

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

    private int bitField0_;
    public static final int RECEIVER_FIELD_NUMBER = 1;
    private org.apache.drill.exec.proto.ExecProtos.FragmentHandle receiver_;
    /**
     * <code>optional .exec.bit.FragmentHandle receiver = 1;</code>
     * @return Whether the receiver field is set.
     */
    @java.lang.Override
    public boolean hasReceiver() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional .exec.bit.FragmentHandle receiver = 1;</code>
     * @return The receiver.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.ExecProtos.FragmentHandle getReceiver() {
      return receiver_ == null ? org.apache.drill.exec.proto.ExecProtos.FragmentHandle.getDefaultInstance() : receiver_;
    }
    /**
     * <code>optional .exec.bit.FragmentHandle receiver = 1;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.ExecProtos.FragmentHandleOrBuilder getReceiverOrBuilder() {
      return receiver_ == null ? org.apache.drill.exec.proto.ExecProtos.FragmentHandle.getDefaultInstance() : receiver_;
    }

    public static final int SENDER_FIELD_NUMBER = 2;
    private org.apache.drill.exec.proto.ExecProtos.FragmentHandle sender_;
    /**
     * <code>optional .exec.bit.FragmentHandle sender = 2;</code>
     * @return Whether the sender field is set.
     */
    @java.lang.Override
    public boolean hasSender() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .exec.bit.FragmentHandle sender = 2;</code>
     * @return The sender.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.ExecProtos.FragmentHandle getSender() {
      return sender_ == null ? org.apache.drill.exec.proto.ExecProtos.FragmentHandle.getDefaultInstance() : sender_;
    }
    /**
     * <code>optional .exec.bit.FragmentHandle sender = 2;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.ExecProtos.FragmentHandleOrBuilder getSenderOrBuilder() {
      return sender_ == null ? org.apache.drill.exec.proto.ExecProtos.FragmentHandle.getDefaultInstance() : sender_;
    }

    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, getReceiver());
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeMessage(2, getSender());
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, getReceiver());
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, getSender());
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.BitControl.FinishedReceiver)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.BitControl.FinishedReceiver other = (org.apache.drill.exec.proto.BitControl.FinishedReceiver) obj;

      if (hasReceiver() != other.hasReceiver()) return false;
      if (hasReceiver()) {
        if (!getReceiver()
            .equals(other.getReceiver())) return false;
      }
      if (hasSender() != other.hasSender()) return false;
      if (hasSender()) {
        if (!getSender()
            .equals(other.getSender())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasReceiver()) {
        hash = (37 * hash) + RECEIVER_FIELD_NUMBER;
        hash = (53 * hash) + getReceiver().hashCode();
      }
      if (hasSender()) {
        hash = (37 * hash) + SENDER_FIELD_NUMBER;
        hash = (53 * hash) + getSender().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

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

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

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

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getReceiverFieldBuilder();
          getSenderFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        if (receiverBuilder_ == null) {
          receiver_ = null;
        } else {
          receiverBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        if (senderBuilder_ == null) {
          sender_ = null;
        } else {
          senderBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

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

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

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

      @java.lang.Override
      public org.apache.drill.exec.proto.BitControl.FinishedReceiver buildPartial() {
        org.apache.drill.exec.proto.BitControl.FinishedReceiver result = new org.apache.drill.exec.proto.BitControl.FinishedReceiver(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          if (receiverBuilder_ == null) {
            result.receiver_ = receiver_;
          } else {
            result.receiver_ = receiverBuilder_.build();
          }
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          if (senderBuilder_ == null) {
            result.sender_ = sender_;
          } else {
            result.sender_ = senderBuilder_.build();
          }
          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.BitControl.FinishedReceiver) {
          return mergeFrom((org.apache.drill.exec.proto.BitControl.FinishedReceiver)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.BitControl.FinishedReceiver other) {
        if (other == org.apache.drill.exec.proto.BitControl.FinishedReceiver.getDefaultInstance()) return this;
        if (other.hasReceiver()) {
          mergeReceiver(other.getReceiver());
        }
        if (other.hasSender()) {
          mergeSender(other.getSender());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

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

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                input.readMessage(
                    getReceiverFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 18: {
                input.readMessage(
                    getSenderFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private org.apache.drill.exec.proto.ExecProtos.FragmentHandle receiver_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.ExecProtos.FragmentHandle, org.apache.drill.exec.proto.ExecProtos.FragmentHandle.Builder, org.apache.drill.exec.proto.ExecProtos.FragmentHandleOrBuilder> receiverBuilder_;
      /**
       * <code>optional .exec.bit.FragmentHandle receiver = 1;</code>
       * @return Whether the receiver field is set.
       */
      public boolean hasReceiver() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .exec.bit.FragmentHandle receiver = 1;</code>
       * @return The receiver.
       */
      public org.apache.drill.exec.proto.ExecProtos.FragmentHandle getReceiver() {
        if (receiverBuilder_ == null) {
          return receiver_ == null ? org.apache.drill.exec.proto.ExecProtos.FragmentHandle.getDefaultInstance() : receiver_;
        } else {
          return receiverBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.bit.FragmentHandle receiver = 1;</code>
       */
      public Builder setReceiver(org.apache.drill.exec.proto.ExecProtos.FragmentHandle value) {
        if (receiverBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          receiver_ = value;
          onChanged();
        } else {
          receiverBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.bit.FragmentHandle receiver = 1;</code>
       */
      public Builder setReceiver(
          org.apache.drill.exec.proto.ExecProtos.FragmentHandle.Builder builderForValue) {
        if (receiverBuilder_ == null) {
          receiver_ = builderForValue.build();
          onChanged();
        } else {
          receiverBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.bit.FragmentHandle receiver = 1;</code>
       */
      public Builder mergeReceiver(org.apache.drill.exec.proto.ExecProtos.FragmentHandle value) {
        if (receiverBuilder_ == null) {
          if (((bitField0_ & 0x00000001) != 0) &&
              receiver_ != null &&
              receiver_ != org.apache.drill.exec.proto.ExecProtos.FragmentHandle.getDefaultInstance()) {
            receiver_ =
              org.apache.drill.exec.proto.ExecProtos.FragmentHandle.newBuilder(receiver_).mergeFrom(value).buildPartial();
          } else {
            receiver_ = value;
          }
          onChanged();
        } else {
          receiverBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.bit.FragmentHandle receiver = 1;</code>
       */
      public Builder clearReceiver() {
        if (receiverBuilder_ == null) {
          receiver_ = null;
          onChanged();
        } else {
          receiverBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>optional .exec.bit.FragmentHandle receiver = 1;</code>
       */
      public org.apache.drill.exec.proto.ExecProtos.FragmentHandle.Builder getReceiverBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getReceiverFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.bit.FragmentHandle receiver = 1;</code>
       */
      public org.apache.drill.exec.proto.ExecProtos.FragmentHandleOrBuilder getReceiverOrBuilder() {
        if (receiverBuilder_ != null) {
          return receiverBuilder_.getMessageOrBuilder();
        } else {
          return receiver_ == null ?
              org.apache.drill.exec.proto.ExecProtos.FragmentHandle.getDefaultInstance() : receiver_;
        }
      }
      /**
       * <code>optional .exec.bit.FragmentHandle receiver = 1;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.ExecProtos.FragmentHandle, org.apache.drill.exec.proto.ExecProtos.FragmentHandle.Builder, org.apache.drill.exec.proto.ExecProtos.FragmentHandleOrBuilder> 
          getReceiverFieldBuilder() {
        if (receiverBuilder_ == null) {
          receiverBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.ExecProtos.FragmentHandle, org.apache.drill.exec.proto.ExecProtos.FragmentHandle.Builder, org.apache.drill.exec.proto.ExecProtos.FragmentHandleOrBuilder>(
                  getReceiver(),
                  getParentForChildren(),
                  isClean());
          receiver_ = null;
        }
        return receiverBuilder_;
      }

      private org.apache.drill.exec.proto.ExecProtos.FragmentHandle sender_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.ExecProtos.FragmentHandle, org.apache.drill.exec.proto.ExecProtos.FragmentHandle.Builder, org.apache.drill.exec.proto.ExecProtos.FragmentHandleOrBuilder> senderBuilder_;
      /**
       * <code>optional .exec.bit.FragmentHandle sender = 2;</code>
       * @return Whether the sender field is set.
       */
      public boolean hasSender() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional .exec.bit.FragmentHandle sender = 2;</code>
       * @return The sender.
       */
      public org.apache.drill.exec.proto.ExecProtos.FragmentHandle getSender() {
        if (senderBuilder_ == null) {
          return sender_ == null ? org.apache.drill.exec.proto.ExecProtos.FragmentHandle.getDefaultInstance() : sender_;
        } else {
          return senderBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.bit.FragmentHandle sender = 2;</code>
       */
      public Builder setSender(org.apache.drill.exec.proto.ExecProtos.FragmentHandle value) {
        if (senderBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          sender_ = value;
          onChanged();
        } else {
          senderBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.bit.FragmentHandle sender = 2;</code>
       */
      public Builder setSender(
          org.apache.drill.exec.proto.ExecProtos.FragmentHandle.Builder builderForValue) {
        if (senderBuilder_ == null) {
          sender_ = builderForValue.build();
          onChanged();
        } else {
          senderBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.bit.FragmentHandle sender = 2;</code>
       */
      public Builder mergeSender(org.apache.drill.exec.proto.ExecProtos.FragmentHandle value) {
        if (senderBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0) &&
              sender_ != null &&
              sender_ != org.apache.drill.exec.proto.ExecProtos.FragmentHandle.getDefaultInstance()) {
            sender_ =
              org.apache.drill.exec.proto.ExecProtos.FragmentHandle.newBuilder(sender_).mergeFrom(value).buildPartial();
          } else {
            sender_ = value;
          }
          onChanged();
        } else {
          senderBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.bit.FragmentHandle sender = 2;</code>
       */
      public Builder clearSender() {
        if (senderBuilder_ == null) {
          sender_ = null;
          onChanged();
        } else {
          senderBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>optional .exec.bit.FragmentHandle sender = 2;</code>
       */
      public org.apache.drill.exec.proto.ExecProtos.FragmentHandle.Builder getSenderBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getSenderFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.bit.FragmentHandle sender = 2;</code>
       */
      public org.apache.drill.exec.proto.ExecProtos.FragmentHandleOrBuilder getSenderOrBuilder() {
        if (senderBuilder_ != null) {
          return senderBuilder_.getMessageOrBuilder();
        } else {
          return sender_ == null ?
              org.apache.drill.exec.proto.ExecProtos.FragmentHandle.getDefaultInstance() : sender_;
        }
      }
      /**
       * <code>optional .exec.bit.FragmentHandle sender = 2;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.ExecProtos.FragmentHandle, org.apache.drill.exec.proto.ExecProtos.FragmentHandle.Builder, org.apache.drill.exec.proto.ExecProtos.FragmentHandleOrBuilder> 
          getSenderFieldBuilder() {
        if (senderBuilder_ == null) {
          senderBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.ExecProtos.FragmentHandle, org.apache.drill.exec.proto.ExecProtos.FragmentHandle.Builder, org.apache.drill.exec.proto.ExecProtos.FragmentHandleOrBuilder>(
                  getSender(),
                  getParentForChildren(),
                  isClean());
          sender_ = null;
        }
        return senderBuilder_;
      }
      @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.bit.control.FinishedReceiver)
    }

    // @@protoc_insertion_point(class_scope:exec.bit.control.FinishedReceiver)
    private static final org.apache.drill.exec.proto.BitControl.FinishedReceiver DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.BitControl.FinishedReceiver();
    }

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

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

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

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

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

  }

  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_bit_control_BitControlHandshake_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_bit_control_BitControlHandshake_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_bit_control_BitStatus_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_bit_control_BitStatus_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_bit_control_FragmentStatus_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_bit_control_FragmentStatus_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_bit_control_InitializeFragments_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_bit_control_InitializeFragments_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_bit_control_CustomMessage_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_bit_control_CustomMessage_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_bit_control_PlanFragment_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_bit_control_PlanFragment_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_bit_control_Collector_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_bit_control_Collector_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_bit_control_QueryContextInformation_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_bit_control_QueryContextInformation_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_bit_control_WorkQueueStatus_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_bit_control_WorkQueueStatus_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_bit_control_FinishedReceiver_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_bit_control_FinishedReceiver_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\020BitControl.proto\022\020exec.bit.control\032\025Ex" +
      "ecutionProtos.proto\032\022Coordination.proto\032" +
      "\023UserBitShared.proto\"\255\001\n\023BitControlHands" +
      "hake\022\023\n\013rpc_version\030\001 \001(\005\0225\n\007channel\030\002 \001" +
      "(\0162\027.exec.shared.RpcChannel:\013BIT_CONTROL" +
      "\022(\n\010endpoint\030\003 \001(\0132\026.exec.DrillbitEndpoi" +
      "nt\022 \n\030authenticationMechanisms\030\004 \003(\t\"F\n\t" +
      "BitStatus\0229\n\017fragment_status\030\001 \003(\0132 .exe" +
      "c.bit.control.FragmentStatus\"n\n\016Fragment" +
      "Status\0222\n\007profile\030\001 \001(\0132!.exec.shared.Mi" +
      "norFragmentProfile\022(\n\006handle\030\002 \001(\0132\030.exe" +
      "c.bit.FragmentHandle\"G\n\023InitializeFragme" +
      "nts\0220\n\010fragment\030\001 \003(\0132\036.exec.bit.control" +
      ".PlanFragment\".\n\rCustomMessage\022\014\n\004type\030\001" +
      " \001(\005\022\017\n\007message\030\002 \001(\014\"\374\003\n\014PlanFragment\022(" +
      "\n\006handle\030\001 \001(\0132\030.exec.bit.FragmentHandle" +
      "\022\024\n\014network_cost\030\004 \001(\002\022\020\n\010cpu_cost\030\005 \001(\002" +
      "\022\021\n\tdisk_cost\030\006 \001(\002\022\023\n\013memory_cost\030\007 \001(\002" +
      "\022\025\n\rfragment_json\030\010 \001(\t\022\025\n\rleaf_fragment" +
      "\030\t \001(\010\022*\n\nassignment\030\n \001(\0132\026.exec.Drillb" +
      "itEndpoint\022\'\n\007foreman\030\013 \001(\0132\026.exec.Drill" +
      "bitEndpoint\022\035\n\013mem_initial\030\014 \001(\003:\010200000" +
      "00\022\033\n\007mem_max\030\r \001(\003:\n2000000000\0221\n\013crede" +
      "ntials\030\016 \001(\0132\034.exec.shared.UserCredentia" +
      "ls\022\024\n\014options_json\030\017 \001(\t\022:\n\007context\030\020 \001(" +
      "\0132).exec.bit.control.QueryContextInforma" +
      "tion\022.\n\tcollector\030\021 \003(\0132\033.exec.bit.contr" +
      "ol.Collector\"\243\001\n\tCollector\022\"\n\032opposite_m" +
      "ajor_fragment_id\030\001 \001(\005\022#\n\027incoming_minor" +
      "_fragment\030\002 \003(\005B\002\020\001\022\035\n\025supports_out_of_o" +
      "rder\030\003 \001(\010\022\023\n\013is_spooling\030\004 \001(\010\022\031\n\021enabl" +
      "e_dynamic_fc\030\005 \001(\010\"w\n\027QueryContextInform" +
      "ation\022\030\n\020query_start_time\030\001 \001(\003\022\021\n\ttime_" +
      "zone\030\002 \001(\005\022\033\n\023default_schema_name\030\003 \001(\t\022" +
      "\022\n\nsession_id\030\004 \001(\t\"f\n\017WorkQueueStatus\022(" +
      "\n\010endpoint\030\001 \001(\0132\026.exec.DrillbitEndpoint" +
      "\022\024\n\014queue_length\030\002 \001(\005\022\023\n\013report_time\030\003 " +
      "\001(\003\"h\n\020FinishedReceiver\022*\n\010receiver\030\001 \001(" +
      "\0132\030.exec.bit.FragmentHandle\022(\n\006sender\030\002 " +
      "\001(\0132\030.exec.bit.FragmentHandle*\206\003\n\007RpcTyp" +
      "e\022\r\n\tHANDSHAKE\020\000\022\007\n\003ACK\020\001\022\013\n\007GOODBYE\020\002\022\034" +
      "\n\030REQ_INITIALIZE_FRAGMENTS\020\003\022\027\n\023REQ_CANC" +
      "EL_FRAGMENT\020\006\022\031\n\025REQ_RECEIVER_FINISHED\020\007" +
      "\022\027\n\023REQ_FRAGMENT_STATUS\020\010\022\022\n\016REQ_BIT_STA" +
      "TUS\020\t\022\024\n\020REQ_QUERY_STATUS\020\n\022\024\n\020REQ_QUERY" +
      "_CANCEL\020\017\022\030\n\024REQ_UNPAUSE_FRAGMENT\020\020\022\016\n\nR" +
      "EQ_CUSTOM\020\021\022\030\n\024RESP_FRAGMENT_HANDLE\020\013\022\030\n" +
      "\024RESP_FRAGMENT_STATUS\020\014\022\023\n\017RESP_BIT_STAT" +
      "US\020\r\022\025\n\021RESP_QUERY_STATUS\020\016\022\017\n\013RESP_CUST" +
      "OM\020\022\022\020\n\014SASL_MESSAGE\020\023B+\n\033org.apache.dri" +
      "ll.exec.protoB\nBitControlH\001"
    };
    descriptor = com.google.protobuf.Descriptors.FileDescriptor
      .internalBuildGeneratedFileFrom(descriptorData,
        new com.google.protobuf.Descriptors.FileDescriptor[] {
          org.apache.drill.exec.proto.ExecProtos.getDescriptor(),
          org.apache.drill.exec.proto.CoordinationProtos.getDescriptor(),
          org.apache.drill.exec.proto.UserBitShared.getDescriptor(),
        });
    internal_static_exec_bit_control_BitControlHandshake_descriptor =
      getDescriptor().getMessageTypes().get(0);
    internal_static_exec_bit_control_BitControlHandshake_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_bit_control_BitControlHandshake_descriptor,
        new java.lang.String[] { "RpcVersion", "Channel", "Endpoint", "AuthenticationMechanisms", });
    internal_static_exec_bit_control_BitStatus_descriptor =
      getDescriptor().getMessageTypes().get(1);
    internal_static_exec_bit_control_BitStatus_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_bit_control_BitStatus_descriptor,
        new java.lang.String[] { "FragmentStatus", });
    internal_static_exec_bit_control_FragmentStatus_descriptor =
      getDescriptor().getMessageTypes().get(2);
    internal_static_exec_bit_control_FragmentStatus_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_bit_control_FragmentStatus_descriptor,
        new java.lang.String[] { "Profile", "Handle", });
    internal_static_exec_bit_control_InitializeFragments_descriptor =
      getDescriptor().getMessageTypes().get(3);
    internal_static_exec_bit_control_InitializeFragments_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_bit_control_InitializeFragments_descriptor,
        new java.lang.String[] { "Fragment", });
    internal_static_exec_bit_control_CustomMessage_descriptor =
      getDescriptor().getMessageTypes().get(4);
    internal_static_exec_bit_control_CustomMessage_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_bit_control_CustomMessage_descriptor,
        new java.lang.String[] { "Type", "Message", });
    internal_static_exec_bit_control_PlanFragment_descriptor =
      getDescriptor().getMessageTypes().get(5);
    internal_static_exec_bit_control_PlanFragment_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_bit_control_PlanFragment_descriptor,
        new java.lang.String[] { "Handle", "NetworkCost", "CpuCost", "DiskCost", "MemoryCost", "FragmentJson", "LeafFragment", "Assignment", "Foreman", "MemInitial", "MemMax", "Credentials", "OptionsJson", "Context", "Collector", });
    internal_static_exec_bit_control_Collector_descriptor =
      getDescriptor().getMessageTypes().get(6);
    internal_static_exec_bit_control_Collector_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_bit_control_Collector_descriptor,
        new java.lang.String[] { "OppositeMajorFragmentId", "IncomingMinorFragment", "SupportsOutOfOrder", "IsSpooling", "EnableDynamicFc", });
    internal_static_exec_bit_control_QueryContextInformation_descriptor =
      getDescriptor().getMessageTypes().get(7);
    internal_static_exec_bit_control_QueryContextInformation_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_bit_control_QueryContextInformation_descriptor,
        new java.lang.String[] { "QueryStartTime", "TimeZone", "DefaultSchemaName", "SessionId", });
    internal_static_exec_bit_control_WorkQueueStatus_descriptor =
      getDescriptor().getMessageTypes().get(8);
    internal_static_exec_bit_control_WorkQueueStatus_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_bit_control_WorkQueueStatus_descriptor,
        new java.lang.String[] { "Endpoint", "QueueLength", "ReportTime", });
    internal_static_exec_bit_control_FinishedReceiver_descriptor =
      getDescriptor().getMessageTypes().get(9);
    internal_static_exec_bit_control_FinishedReceiver_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_bit_control_FinishedReceiver_descriptor,
        new java.lang.String[] { "Receiver", "Sender", });
    org.apache.drill.exec.proto.ExecProtos.getDescriptor();
    org.apache.drill.exec.proto.CoordinationProtos.getDescriptor();
    org.apache.drill.exec.proto.UserBitShared.getDescriptor();
  }

  // @@protoc_insertion_point(outer_class_scope)
}
