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

package org.apache.drill.common.types;

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

  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistry registry) {
    registerAllExtensions(
        (com.google.protobuf.ExtensionRegistryLite) registry);
  }
  /**
   * Protobuf enum {@code common.MinorType}
   */
  public enum MinorType
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <pre>
     *  late binding type
     * </pre>
     *
     * <code>LATE = 0;</code>
     */
    LATE(0),
    /**
     * <pre>
     *  an empty map column.  Useful for conceptual setup.  Children listed within here
     * </pre>
     *
     * <code>MAP = 1;</code>
     */
    MAP(1),
    /**
     * <pre>
     *  single byte signed integer
     * </pre>
     *
     * <code>TINYINT = 3;</code>
     */
    TINYINT(3),
    /**
     * <pre>
     *  two byte signed integer
     * </pre>
     *
     * <code>SMALLINT = 4;</code>
     */
    SMALLINT(4),
    /**
     * <pre>
     *  four byte signed integer
     * </pre>
     *
     * <code>INT = 5;</code>
     */
    INT(5),
    /**
     * <pre>
     *  eight byte signed integer
     * </pre>
     *
     * <code>BIGINT = 6;</code>
     */
    BIGINT(6),
    /**
     * <pre>
     *  a decimal supporting precision between 1 and 9
     * </pre>
     *
     * <code>DECIMAL9 = 7;</code>
     */
    DECIMAL9(7),
    /**
     * <pre>
     *  a decimal supporting precision between 10 and 18
     * </pre>
     *
     * <code>DECIMAL18 = 8;</code>
     */
    DECIMAL18(8),
    /**
     * <pre>
     *  a decimal supporting precision between 19 and 28
     * </pre>
     *
     * <code>DECIMAL28SPARSE = 9;</code>
     */
    DECIMAL28SPARSE(9),
    /**
     * <pre>
     *  a decimal supporting precision between 29 and 38
     * </pre>
     *
     * <code>DECIMAL38SPARSE = 10;</code>
     */
    DECIMAL38SPARSE(10),
    /**
     * <pre>
     *  signed decimal with two digit scale
     * </pre>
     *
     * <code>MONEY = 11;</code>
     */
    MONEY(11),
    /**
     * <pre>
     *  days since 4713bc
     * </pre>
     *
     * <code>DATE = 12;</code>
     */
    DATE(12),
    /**
     * <pre>
     *  time in micros before or after 2000/1/1
     * </pre>
     *
     * <code>TIME = 13;</code>
     */
    TIME(13),
    /**
     * <pre>
     *  time in micros before or after 2000/1/1 with timezone
     * </pre>
     *
     * <code>TIMETZ = 14;</code>
     */
    TIMETZ(14),
    /**
     * <pre>
     *  unix epoch time in millis
     * </pre>
     *
     * <code>TIMESTAMPTZ = 15;</code>
     */
    TIMESTAMPTZ(15),
    /**
     * <pre>
     *  TBD
     * </pre>
     *
     * <code>TIMESTAMP = 16;</code>
     */
    TIMESTAMP(16),
    /**
     * <pre>
     *  TBD
     * </pre>
     *
     * <code>INTERVAL = 17;</code>
     */
    INTERVAL(17),
    /**
     * <pre>
     *  4 byte ieee 754
     * </pre>
     *
     * <code>FLOAT4 = 18;</code>
     */
    FLOAT4(18),
    /**
     * <pre>
     *  8 byte ieee 754
     * </pre>
     *
     * <code>FLOAT8 = 19;</code>
     */
    FLOAT8(19),
    /**
     * <pre>
     *  single bit value (boolean)
     * </pre>
     *
     * <code>BIT = 20;</code>
     */
    BIT(20),
    /**
     * <pre>
     *  utf8 fixed length string, padded with spaces
     * </pre>
     *
     * <code>FIXEDCHAR = 21;</code>
     */
    FIXEDCHAR(21),
    /**
     * <code>FIXED16CHAR = 22;</code>
     */
    FIXED16CHAR(22),
    /**
     * <pre>
     *  fixed length binary, padded with 0 bytes
     * </pre>
     *
     * <code>FIXEDBINARY = 23;</code>
     */
    FIXEDBINARY(23),
    /**
     * <pre>
     *  utf8 variable length string
     * </pre>
     *
     * <code>VARCHAR = 24;</code>
     */
    VARCHAR(24),
    /**
     * <pre>
     * utf16 variable length string
     * </pre>
     *
     * <code>VAR16CHAR = 25;</code>
     */
    VAR16CHAR(25),
    /**
     * <pre>
     *  variable length binary
     * </pre>
     *
     * <code>VARBINARY = 26;</code>
     */
    VARBINARY(26),
    /**
     * <pre>
     *  unsigned 1 byte integer
     * </pre>
     *
     * <code>UINT1 = 29;</code>
     */
    UINT1(29),
    /**
     * <pre>
     *  unsigned 2 byte integer
     * </pre>
     *
     * <code>UINT2 = 30;</code>
     */
    UINT2(30),
    /**
     * <pre>
     *  unsigned 4 byte integer
     * </pre>
     *
     * <code>UINT4 = 31;</code>
     */
    UINT4(31),
    /**
     * <pre>
     *  unsigned 8 byte integer
     * </pre>
     *
     * <code>UINT8 = 32;</code>
     */
    UINT8(32),
    /**
     * <pre>
     * dense decimal representation, supporting precision between 19 and 28
     * </pre>
     *
     * <code>DECIMAL28DENSE = 33;</code>
     */
    DECIMAL28DENSE(33),
    /**
     * <pre>
     * dense decimal representation, supporting precision between 28 and 38
     * </pre>
     *
     * <code>DECIMAL38DENSE = 34;</code>
     */
    DECIMAL38DENSE(34),
    /**
     * <pre>
     *    PROTO2 = 33;   //  protobuf encoded complex type. (up to 2^16 in length)
     *    PROTO4 = 34;   //  protobuf encoded complex type. (up to 2^32 in length)
     *    MSGPACK2 = 35;   //  msgpack encoded complex type. (up to 2^16 in length)
     *    MSGPACK4 = 36;   //  msgpack encoded complex type. (up to 2^32 in length)
     * </pre>
     *
     * <code>NULL = 37;</code>
     */
    NULL(37),
    /**
     * <pre>
     * Interval type specifying YEAR to MONTH
     * </pre>
     *
     * <code>INTERVALYEAR = 38;</code>
     */
    INTERVALYEAR(38),
    /**
     * <pre>
     * Interval type specifying DAY to SECONDS
     * </pre>
     *
     * <code>INTERVALDAY = 39;</code>
     */
    INTERVALDAY(39),
    /**
     * <code>LIST = 40;</code>
     */
    LIST(40),
    /**
     * <code>GENERIC_OBJECT = 41;</code>
     */
    GENERIC_OBJECT(41),
    /**
     * <code>UNION = 42;</code>
     */
    UNION(42),
    /**
     * <pre>
     * variable width decimal (arbitrary precision)
     * </pre>
     *
     * <code>VARDECIMAL = 43;</code>
     */
    VARDECIMAL(43),
    /**
     * <code>DICT = 44;</code>
     */
    DICT(44),
    ;

    /**
     * <pre>
     *  late binding type
     * </pre>
     *
     * <code>LATE = 0;</code>
     */
    public static final int LATE_VALUE = 0;
    /**
     * <pre>
     *  an empty map column.  Useful for conceptual setup.  Children listed within here
     * </pre>
     *
     * <code>MAP = 1;</code>
     */
    public static final int MAP_VALUE = 1;
    /**
     * <pre>
     *  single byte signed integer
     * </pre>
     *
     * <code>TINYINT = 3;</code>
     */
    public static final int TINYINT_VALUE = 3;
    /**
     * <pre>
     *  two byte signed integer
     * </pre>
     *
     * <code>SMALLINT = 4;</code>
     */
    public static final int SMALLINT_VALUE = 4;
    /**
     * <pre>
     *  four byte signed integer
     * </pre>
     *
     * <code>INT = 5;</code>
     */
    public static final int INT_VALUE = 5;
    /**
     * <pre>
     *  eight byte signed integer
     * </pre>
     *
     * <code>BIGINT = 6;</code>
     */
    public static final int BIGINT_VALUE = 6;
    /**
     * <pre>
     *  a decimal supporting precision between 1 and 9
     * </pre>
     *
     * <code>DECIMAL9 = 7;</code>
     */
    public static final int DECIMAL9_VALUE = 7;
    /**
     * <pre>
     *  a decimal supporting precision between 10 and 18
     * </pre>
     *
     * <code>DECIMAL18 = 8;</code>
     */
    public static final int DECIMAL18_VALUE = 8;
    /**
     * <pre>
     *  a decimal supporting precision between 19 and 28
     * </pre>
     *
     * <code>DECIMAL28SPARSE = 9;</code>
     */
    public static final int DECIMAL28SPARSE_VALUE = 9;
    /**
     * <pre>
     *  a decimal supporting precision between 29 and 38
     * </pre>
     *
     * <code>DECIMAL38SPARSE = 10;</code>
     */
    public static final int DECIMAL38SPARSE_VALUE = 10;
    /**
     * <pre>
     *  signed decimal with two digit scale
     * </pre>
     *
     * <code>MONEY = 11;</code>
     */
    public static final int MONEY_VALUE = 11;
    /**
     * <pre>
     *  days since 4713bc
     * </pre>
     *
     * <code>DATE = 12;</code>
     */
    public static final int DATE_VALUE = 12;
    /**
     * <pre>
     *  time in micros before or after 2000/1/1
     * </pre>
     *
     * <code>TIME = 13;</code>
     */
    public static final int TIME_VALUE = 13;
    /**
     * <pre>
     *  time in micros before or after 2000/1/1 with timezone
     * </pre>
     *
     * <code>TIMETZ = 14;</code>
     */
    public static final int TIMETZ_VALUE = 14;
    /**
     * <pre>
     *  unix epoch time in millis
     * </pre>
     *
     * <code>TIMESTAMPTZ = 15;</code>
     */
    public static final int TIMESTAMPTZ_VALUE = 15;
    /**
     * <pre>
     *  TBD
     * </pre>
     *
     * <code>TIMESTAMP = 16;</code>
     */
    public static final int TIMESTAMP_VALUE = 16;
    /**
     * <pre>
     *  TBD
     * </pre>
     *
     * <code>INTERVAL = 17;</code>
     */
    public static final int INTERVAL_VALUE = 17;
    /**
     * <pre>
     *  4 byte ieee 754
     * </pre>
     *
     * <code>FLOAT4 = 18;</code>
     */
    public static final int FLOAT4_VALUE = 18;
    /**
     * <pre>
     *  8 byte ieee 754
     * </pre>
     *
     * <code>FLOAT8 = 19;</code>
     */
    public static final int FLOAT8_VALUE = 19;
    /**
     * <pre>
     *  single bit value (boolean)
     * </pre>
     *
     * <code>BIT = 20;</code>
     */
    public static final int BIT_VALUE = 20;
    /**
     * <pre>
     *  utf8 fixed length string, padded with spaces
     * </pre>
     *
     * <code>FIXEDCHAR = 21;</code>
     */
    public static final int FIXEDCHAR_VALUE = 21;
    /**
     * <code>FIXED16CHAR = 22;</code>
     */
    public static final int FIXED16CHAR_VALUE = 22;
    /**
     * <pre>
     *  fixed length binary, padded with 0 bytes
     * </pre>
     *
     * <code>FIXEDBINARY = 23;</code>
     */
    public static final int FIXEDBINARY_VALUE = 23;
    /**
     * <pre>
     *  utf8 variable length string
     * </pre>
     *
     * <code>VARCHAR = 24;</code>
     */
    public static final int VARCHAR_VALUE = 24;
    /**
     * <pre>
     * utf16 variable length string
     * </pre>
     *
     * <code>VAR16CHAR = 25;</code>
     */
    public static final int VAR16CHAR_VALUE = 25;
    /**
     * <pre>
     *  variable length binary
     * </pre>
     *
     * <code>VARBINARY = 26;</code>
     */
    public static final int VARBINARY_VALUE = 26;
    /**
     * <pre>
     *  unsigned 1 byte integer
     * </pre>
     *
     * <code>UINT1 = 29;</code>
     */
    public static final int UINT1_VALUE = 29;
    /**
     * <pre>
     *  unsigned 2 byte integer
     * </pre>
     *
     * <code>UINT2 = 30;</code>
     */
    public static final int UINT2_VALUE = 30;
    /**
     * <pre>
     *  unsigned 4 byte integer
     * </pre>
     *
     * <code>UINT4 = 31;</code>
     */
    public static final int UINT4_VALUE = 31;
    /**
     * <pre>
     *  unsigned 8 byte integer
     * </pre>
     *
     * <code>UINT8 = 32;</code>
     */
    public static final int UINT8_VALUE = 32;
    /**
     * <pre>
     * dense decimal representation, supporting precision between 19 and 28
     * </pre>
     *
     * <code>DECIMAL28DENSE = 33;</code>
     */
    public static final int DECIMAL28DENSE_VALUE = 33;
    /**
     * <pre>
     * dense decimal representation, supporting precision between 28 and 38
     * </pre>
     *
     * <code>DECIMAL38DENSE = 34;</code>
     */
    public static final int DECIMAL38DENSE_VALUE = 34;
    /**
     * <pre>
     *    PROTO2 = 33;   //  protobuf encoded complex type. (up to 2^16 in length)
     *    PROTO4 = 34;   //  protobuf encoded complex type. (up to 2^32 in length)
     *    MSGPACK2 = 35;   //  msgpack encoded complex type. (up to 2^16 in length)
     *    MSGPACK4 = 36;   //  msgpack encoded complex type. (up to 2^32 in length)
     * </pre>
     *
     * <code>NULL = 37;</code>
     */
    public static final int NULL_VALUE = 37;
    /**
     * <pre>
     * Interval type specifying YEAR to MONTH
     * </pre>
     *
     * <code>INTERVALYEAR = 38;</code>
     */
    public static final int INTERVALYEAR_VALUE = 38;
    /**
     * <pre>
     * Interval type specifying DAY to SECONDS
     * </pre>
     *
     * <code>INTERVALDAY = 39;</code>
     */
    public static final int INTERVALDAY_VALUE = 39;
    /**
     * <code>LIST = 40;</code>
     */
    public static final int LIST_VALUE = 40;
    /**
     * <code>GENERIC_OBJECT = 41;</code>
     */
    public static final int GENERIC_OBJECT_VALUE = 41;
    /**
     * <code>UNION = 42;</code>
     */
    public static final int UNION_VALUE = 42;
    /**
     * <pre>
     * variable width decimal (arbitrary precision)
     * </pre>
     *
     * <code>VARDECIMAL = 43;</code>
     */
    public static final int VARDECIMAL_VALUE = 43;
    /**
     * <code>DICT = 44;</code>
     */
    public static final int DICT_VALUE = 44;


    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 MinorType 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 MinorType forNumber(int value) {
      switch (value) {
        case 0: return LATE;
        case 1: return MAP;
        case 3: return TINYINT;
        case 4: return SMALLINT;
        case 5: return INT;
        case 6: return BIGINT;
        case 7: return DECIMAL9;
        case 8: return DECIMAL18;
        case 9: return DECIMAL28SPARSE;
        case 10: return DECIMAL38SPARSE;
        case 11: return MONEY;
        case 12: return DATE;
        case 13: return TIME;
        case 14: return TIMETZ;
        case 15: return TIMESTAMPTZ;
        case 16: return TIMESTAMP;
        case 17: return INTERVAL;
        case 18: return FLOAT4;
        case 19: return FLOAT8;
        case 20: return BIT;
        case 21: return FIXEDCHAR;
        case 22: return FIXED16CHAR;
        case 23: return FIXEDBINARY;
        case 24: return VARCHAR;
        case 25: return VAR16CHAR;
        case 26: return VARBINARY;
        case 29: return UINT1;
        case 30: return UINT2;
        case 31: return UINT4;
        case 32: return UINT8;
        case 33: return DECIMAL28DENSE;
        case 34: return DECIMAL38DENSE;
        case 37: return NULL;
        case 38: return INTERVALYEAR;
        case 39: return INTERVALDAY;
        case 40: return LIST;
        case 41: return GENERIC_OBJECT;
        case 42: return UNION;
        case 43: return VARDECIMAL;
        case 44: return DICT;
        default: return null;
      }
    }

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

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

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

    // @@protoc_insertion_point(enum_scope:common.MinorType)
  }

  /**
   * Protobuf enum {@code common.DataMode}
   */
  public enum DataMode
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <pre>
     * nullable
     * </pre>
     *
     * <code>OPTIONAL = 0;</code>
     */
    OPTIONAL(0),
    /**
     * <pre>
     * non-nullable
     * </pre>
     *
     * <code>REQUIRED = 1;</code>
     */
    REQUIRED(1),
    /**
     * <pre>
     * single, repeated-field
     * </pre>
     *
     * <code>REPEATED = 2;</code>
     */
    REPEATED(2),
    ;

    /**
     * <pre>
     * nullable
     * </pre>
     *
     * <code>OPTIONAL = 0;</code>
     */
    public static final int OPTIONAL_VALUE = 0;
    /**
     * <pre>
     * non-nullable
     * </pre>
     *
     * <code>REQUIRED = 1;</code>
     */
    public static final int REQUIRED_VALUE = 1;
    /**
     * <pre>
     * single, repeated-field
     * </pre>
     *
     * <code>REPEATED = 2;</code>
     */
    public static final int REPEATED_VALUE = 2;


    public final int getNumber() {
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static DataMode 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 DataMode forNumber(int value) {
      switch (value) {
        case 0: return OPTIONAL;
        case 1: return REQUIRED;
        case 2: return REPEATED;
        default: return null;
      }
    }

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

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

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

    // @@protoc_insertion_point(enum_scope:common.DataMode)
  }

  public interface MajorTypeOrBuilder extends
      // @@protoc_insertion_point(interface_extends:common.MajorType)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional .common.MinorType minor_type = 1;</code>
     * @return Whether the minorType field is set.
     */
    boolean hasMinorType();
    /**
     * <code>optional .common.MinorType minor_type = 1;</code>
     * @return The minorType.
     */
    org.apache.drill.common.types.TypeProtos.MinorType getMinorType();

    /**
     * <code>optional .common.DataMode mode = 2;</code>
     * @return Whether the mode field is set.
     */
    boolean hasMode();
    /**
     * <code>optional .common.DataMode mode = 2;</code>
     * @return The mode.
     */
    org.apache.drill.common.types.TypeProtos.DataMode getMode();

    /**
     * <code>optional int32 width = 3;</code>
     * @return Whether the width field is set.
     */
    boolean hasWidth();
    /**
     * <code>optional int32 width = 3;</code>
     * @return The width.
     */
    int getWidth();

    /**
     * <pre>
     * used for decimal types or as optional length for fixed size value
     * </pre>
     *
     * <code>optional int32 precision = 4;</code>
     * @return Whether the precision field is set.
     */
    boolean hasPrecision();
    /**
     * <pre>
     * used for decimal types or as optional length for fixed size value
     * </pre>
     *
     * <code>optional int32 precision = 4;</code>
     * @return The precision.
     */
    int getPrecision();

    /**
     * <pre>
     * used for decimal types
     * </pre>
     *
     * <code>optional int32 scale = 5;</code>
     * @return Whether the scale field is set.
     */
    boolean hasScale();
    /**
     * <pre>
     * used for decimal types
     * </pre>
     *
     * <code>optional int32 scale = 5;</code>
     * @return The scale.
     */
    int getScale();

    /**
     * <pre>
     * used by TimeStamp type
     * </pre>
     *
     * <code>optional int32 timeZone = 6;</code>
     * @return Whether the timeZone field is set.
     */
    boolean hasTimeZone();
    /**
     * <pre>
     * used by TimeStamp type
     * </pre>
     *
     * <code>optional int32 timeZone = 6;</code>
     * @return The timeZone.
     */
    int getTimeZone();

    /**
     * <pre>
     * used by Union type
     * </pre>
     *
     * <code>repeated .common.MinorType sub_type = 7;</code>
     * @return A list containing the subType.
     */
    java.util.List<org.apache.drill.common.types.TypeProtos.MinorType> getSubTypeList();
    /**
     * <pre>
     * used by Union type
     * </pre>
     *
     * <code>repeated .common.MinorType sub_type = 7;</code>
     * @return The count of subType.
     */
    int getSubTypeCount();
    /**
     * <pre>
     * used by Union type
     * </pre>
     *
     * <code>repeated .common.MinorType sub_type = 7;</code>
     * @param index The index of the element to return.
     * @return The subType at the given index.
     */
    org.apache.drill.common.types.TypeProtos.MinorType getSubType(int index);
  }
  /**
   * Protobuf type {@code common.MajorType}
   */
  public static final class MajorType extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:common.MajorType)
      MajorTypeOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use MajorType.newBuilder() to construct.
    private MajorType(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private MajorType() {
      minorType_ = 0;
      mode_ = 0;
      subType_ = java.util.Collections.emptyList();
    }

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

    @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.common.types.TypeProtos.internal_static_common_MajorType_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.common.types.TypeProtos.internal_static_common_MajorType_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.common.types.TypeProtos.MajorType.class, org.apache.drill.common.types.TypeProtos.MajorType.Builder.class);
    }

    private int bitField0_;
    public static final int MINOR_TYPE_FIELD_NUMBER = 1;
    private int minorType_;
    /**
     * <code>optional .common.MinorType minor_type = 1;</code>
     * @return Whether the minorType field is set.
     */
    @java.lang.Override public boolean hasMinorType() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional .common.MinorType minor_type = 1;</code>
     * @return The minorType.
     */
    @java.lang.Override public org.apache.drill.common.types.TypeProtos.MinorType getMinorType() {
      @SuppressWarnings("deprecation")
      org.apache.drill.common.types.TypeProtos.MinorType result = org.apache.drill.common.types.TypeProtos.MinorType.valueOf(minorType_);
      return result == null ? org.apache.drill.common.types.TypeProtos.MinorType.LATE : result;
    }

    public static final int MODE_FIELD_NUMBER = 2;
    private int mode_;
    /**
     * <code>optional .common.DataMode mode = 2;</code>
     * @return Whether the mode field is set.
     */
    @java.lang.Override public boolean hasMode() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .common.DataMode mode = 2;</code>
     * @return The mode.
     */
    @java.lang.Override public org.apache.drill.common.types.TypeProtos.DataMode getMode() {
      @SuppressWarnings("deprecation")
      org.apache.drill.common.types.TypeProtos.DataMode result = org.apache.drill.common.types.TypeProtos.DataMode.valueOf(mode_);
      return result == null ? org.apache.drill.common.types.TypeProtos.DataMode.OPTIONAL : result;
    }

    public static final int WIDTH_FIELD_NUMBER = 3;
    private int width_;
    /**
     * <code>optional int32 width = 3;</code>
     * @return Whether the width field is set.
     */
    @java.lang.Override
    public boolean hasWidth() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional int32 width = 3;</code>
     * @return The width.
     */
    @java.lang.Override
    public int getWidth() {
      return width_;
    }

    public static final int PRECISION_FIELD_NUMBER = 4;
    private int precision_;
    /**
     * <pre>
     * used for decimal types or as optional length for fixed size value
     * </pre>
     *
     * <code>optional int32 precision = 4;</code>
     * @return Whether the precision field is set.
     */
    @java.lang.Override
    public boolean hasPrecision() {
      return ((bitField0_ & 0x00000008) != 0);
    }
    /**
     * <pre>
     * used for decimal types or as optional length for fixed size value
     * </pre>
     *
     * <code>optional int32 precision = 4;</code>
     * @return The precision.
     */
    @java.lang.Override
    public int getPrecision() {
      return precision_;
    }

    public static final int SCALE_FIELD_NUMBER = 5;
    private int scale_;
    /**
     * <pre>
     * used for decimal types
     * </pre>
     *
     * <code>optional int32 scale = 5;</code>
     * @return Whether the scale field is set.
     */
    @java.lang.Override
    public boolean hasScale() {
      return ((bitField0_ & 0x00000010) != 0);
    }
    /**
     * <pre>
     * used for decimal types
     * </pre>
     *
     * <code>optional int32 scale = 5;</code>
     * @return The scale.
     */
    @java.lang.Override
    public int getScale() {
      return scale_;
    }

    public static final int TIMEZONE_FIELD_NUMBER = 6;
    private int timeZone_;
    /**
     * <pre>
     * used by TimeStamp type
     * </pre>
     *
     * <code>optional int32 timeZone = 6;</code>
     * @return Whether the timeZone field is set.
     */
    @java.lang.Override
    public boolean hasTimeZone() {
      return ((bitField0_ & 0x00000020) != 0);
    }
    /**
     * <pre>
     * used by TimeStamp type
     * </pre>
     *
     * <code>optional int32 timeZone = 6;</code>
     * @return The timeZone.
     */
    @java.lang.Override
    public int getTimeZone() {
      return timeZone_;
    }

    public static final int SUB_TYPE_FIELD_NUMBER = 7;
    private java.util.List<java.lang.Integer> subType_;
    private static final com.google.protobuf.Internal.ListAdapter.Converter<
        java.lang.Integer, org.apache.drill.common.types.TypeProtos.MinorType> subType_converter_ =
            new com.google.protobuf.Internal.ListAdapter.Converter<
                java.lang.Integer, org.apache.drill.common.types.TypeProtos.MinorType>() {
              public org.apache.drill.common.types.TypeProtos.MinorType convert(java.lang.Integer from) {
                @SuppressWarnings("deprecation")
                org.apache.drill.common.types.TypeProtos.MinorType result = org.apache.drill.common.types.TypeProtos.MinorType.valueOf(from);
                return result == null ? org.apache.drill.common.types.TypeProtos.MinorType.LATE : result;
              }
            };
    /**
     * <pre>
     * used by Union type
     * </pre>
     *
     * <code>repeated .common.MinorType sub_type = 7;</code>
     * @return A list containing the subType.
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.common.types.TypeProtos.MinorType> getSubTypeList() {
      return new com.google.protobuf.Internal.ListAdapter<
          java.lang.Integer, org.apache.drill.common.types.TypeProtos.MinorType>(subType_, subType_converter_);
    }
    /**
     * <pre>
     * used by Union type
     * </pre>
     *
     * <code>repeated .common.MinorType sub_type = 7;</code>
     * @return The count of subType.
     */
    @java.lang.Override
    public int getSubTypeCount() {
      return subType_.size();
    }
    /**
     * <pre>
     * used by Union type
     * </pre>
     *
     * <code>repeated .common.MinorType sub_type = 7;</code>
     * @param index The index of the element to return.
     * @return The subType at the given index.
     */
    @java.lang.Override
    public org.apache.drill.common.types.TypeProtos.MinorType getSubType(int index) {
      return subType_converter_.convert(subType_.get(index));
    }

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

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeEnum(1, minorType_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeEnum(2, mode_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeInt32(3, width_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        output.writeInt32(4, precision_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        output.writeInt32(5, scale_);
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        output.writeInt32(6, timeZone_);
      }
      for (int i = 0; i < subType_.size(); i++) {
        output.writeEnum(7, subType_.get(i));
      }
      getUnknownFields().writeTo(output);
    }

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

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(1, minorType_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(2, mode_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(3, width_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(4, precision_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(5, scale_);
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(6, timeZone_);
      }
      {
        int dataSize = 0;
        for (int i = 0; i < subType_.size(); i++) {
          dataSize += com.google.protobuf.CodedOutputStream
            .computeEnumSizeNoTag(subType_.get(i));
        }
        size += dataSize;
        size += 1 * subType_.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.common.types.TypeProtos.MajorType)) {
        return super.equals(obj);
      }
      org.apache.drill.common.types.TypeProtos.MajorType other = (org.apache.drill.common.types.TypeProtos.MajorType) obj;

      if (hasMinorType() != other.hasMinorType()) return false;
      if (hasMinorType()) {
        if (minorType_ != other.minorType_) return false;
      }
      if (hasMode() != other.hasMode()) return false;
      if (hasMode()) {
        if (mode_ != other.mode_) return false;
      }
      if (hasWidth() != other.hasWidth()) return false;
      if (hasWidth()) {
        if (getWidth()
            != other.getWidth()) return false;
      }
      if (hasPrecision() != other.hasPrecision()) return false;
      if (hasPrecision()) {
        if (getPrecision()
            != other.getPrecision()) return false;
      }
      if (hasScale() != other.hasScale()) return false;
      if (hasScale()) {
        if (getScale()
            != other.getScale()) return false;
      }
      if (hasTimeZone() != other.hasTimeZone()) return false;
      if (hasTimeZone()) {
        if (getTimeZone()
            != other.getTimeZone()) return false;
      }
      if (!subType_.equals(other.subType_)) 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 (hasMinorType()) {
        hash = (37 * hash) + MINOR_TYPE_FIELD_NUMBER;
        hash = (53 * hash) + minorType_;
      }
      if (hasMode()) {
        hash = (37 * hash) + MODE_FIELD_NUMBER;
        hash = (53 * hash) + mode_;
      }
      if (hasWidth()) {
        hash = (37 * hash) + WIDTH_FIELD_NUMBER;
        hash = (53 * hash) + getWidth();
      }
      if (hasPrecision()) {
        hash = (37 * hash) + PRECISION_FIELD_NUMBER;
        hash = (53 * hash) + getPrecision();
      }
      if (hasScale()) {
        hash = (37 * hash) + SCALE_FIELD_NUMBER;
        hash = (53 * hash) + getScale();
      }
      if (hasTimeZone()) {
        hash = (37 * hash) + TIMEZONE_FIELD_NUMBER;
        hash = (53 * hash) + getTimeZone();
      }
      if (getSubTypeCount() > 0) {
        hash = (37 * hash) + SUB_TYPE_FIELD_NUMBER;
        hash = (53 * hash) + subType_.hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

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

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.common.types.TypeProtos.internal_static_common_MajorType_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.common.types.TypeProtos.MajorType.class, org.apache.drill.common.types.TypeProtos.MajorType.Builder.class);
      }

      // Construct using org.apache.drill.common.types.TypeProtos.MajorType.newBuilder()
      private Builder() {

      }

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

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        minorType_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        mode_ = 0;
        bitField0_ = (bitField0_ & ~0x00000002);
        width_ = 0;
        bitField0_ = (bitField0_ & ~0x00000004);
        precision_ = 0;
        bitField0_ = (bitField0_ & ~0x00000008);
        scale_ = 0;
        bitField0_ = (bitField0_ & ~0x00000010);
        timeZone_ = 0;
        bitField0_ = (bitField0_ & ~0x00000020);
        subType_ = java.util.Collections.emptyList();
        bitField0_ = (bitField0_ & ~0x00000040);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.common.types.TypeProtos.internal_static_common_MajorType_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.common.types.TypeProtos.MajorType getDefaultInstanceForType() {
        return org.apache.drill.common.types.TypeProtos.MajorType.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.common.types.TypeProtos.MajorType build() {
        org.apache.drill.common.types.TypeProtos.MajorType result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.common.types.TypeProtos.MajorType buildPartial() {
        org.apache.drill.common.types.TypeProtos.MajorType result = new org.apache.drill.common.types.TypeProtos.MajorType(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.minorType_ = minorType_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          to_bitField0_ |= 0x00000002;
        }
        result.mode_ = mode_;
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.width_ = width_;
          to_bitField0_ |= 0x00000004;
        }
        if (((from_bitField0_ & 0x00000008) != 0)) {
          result.precision_ = precision_;
          to_bitField0_ |= 0x00000008;
        }
        if (((from_bitField0_ & 0x00000010) != 0)) {
          result.scale_ = scale_;
          to_bitField0_ |= 0x00000010;
        }
        if (((from_bitField0_ & 0x00000020) != 0)) {
          result.timeZone_ = timeZone_;
          to_bitField0_ |= 0x00000020;
        }
        if (((bitField0_ & 0x00000040) != 0)) {
          subType_ = java.util.Collections.unmodifiableList(subType_);
          bitField0_ = (bitField0_ & ~0x00000040);
        }
        result.subType_ = subType_;
        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.common.types.TypeProtos.MajorType) {
          return mergeFrom((org.apache.drill.common.types.TypeProtos.MajorType)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.common.types.TypeProtos.MajorType other) {
        if (other == org.apache.drill.common.types.TypeProtos.MajorType.getDefaultInstance()) return this;
        if (other.hasMinorType()) {
          setMinorType(other.getMinorType());
        }
        if (other.hasMode()) {
          setMode(other.getMode());
        }
        if (other.hasWidth()) {
          setWidth(other.getWidth());
        }
        if (other.hasPrecision()) {
          setPrecision(other.getPrecision());
        }
        if (other.hasScale()) {
          setScale(other.getScale());
        }
        if (other.hasTimeZone()) {
          setTimeZone(other.getTimeZone());
        }
        if (!other.subType_.isEmpty()) {
          if (subType_.isEmpty()) {
            subType_ = other.subType_;
            bitField0_ = (bitField0_ & ~0x00000040);
          } else {
            ensureSubTypeIsMutable();
            subType_.addAll(other.subType_);
          }
          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: {
                int tmpRaw = input.readEnum();
                org.apache.drill.common.types.TypeProtos.MinorType tmpValue =
                    org.apache.drill.common.types.TypeProtos.MinorType.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(1, tmpRaw);
                } else {
                  minorType_ = tmpRaw;
                  bitField0_ |= 0x00000001;
                }
                break;
              } // case 8
              case 16: {
                int tmpRaw = input.readEnum();
                org.apache.drill.common.types.TypeProtos.DataMode tmpValue =
                    org.apache.drill.common.types.TypeProtos.DataMode.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(2, tmpRaw);
                } else {
                  mode_ = tmpRaw;
                  bitField0_ |= 0x00000002;
                }
                break;
              } // case 16
              case 24: {
                width_ = input.readInt32();
                bitField0_ |= 0x00000004;
                break;
              } // case 24
              case 32: {
                precision_ = input.readInt32();
                bitField0_ |= 0x00000008;
                break;
              } // case 32
              case 40: {
                scale_ = input.readInt32();
                bitField0_ |= 0x00000010;
                break;
              } // case 40
              case 48: {
                timeZone_ = input.readInt32();
                bitField0_ |= 0x00000020;
                break;
              } // case 48
              case 56: {
                int tmpRaw = input.readEnum();
                org.apache.drill.common.types.TypeProtos.MinorType tmpValue =
                    org.apache.drill.common.types.TypeProtos.MinorType.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(7, tmpRaw);
                } else {
                  ensureSubTypeIsMutable();
                  subType_.add(tmpRaw);
                }
                break;
              } // case 56
              case 58: {
                int length = input.readRawVarint32();
                int oldLimit = input.pushLimit(length);
                while(input.getBytesUntilLimit() > 0) {
                  int tmpRaw = input.readEnum();
                  org.apache.drill.common.types.TypeProtos.MinorType tmpValue =
                      org.apache.drill.common.types.TypeProtos.MinorType.forNumber(tmpRaw);
                  if (tmpValue == null) {
                    mergeUnknownVarintField(7, tmpRaw);
                  } else {
                    ensureSubTypeIsMutable();
                    subType_.add(tmpRaw);
                  }
                }
                input.popLimit(oldLimit);
                break;
              } // case 58
              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 minorType_ = 0;
      /**
       * <code>optional .common.MinorType minor_type = 1;</code>
       * @return Whether the minorType field is set.
       */
      @java.lang.Override public boolean hasMinorType() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .common.MinorType minor_type = 1;</code>
       * @return The minorType.
       */
      @java.lang.Override
      public org.apache.drill.common.types.TypeProtos.MinorType getMinorType() {
        @SuppressWarnings("deprecation")
        org.apache.drill.common.types.TypeProtos.MinorType result = org.apache.drill.common.types.TypeProtos.MinorType.valueOf(minorType_);
        return result == null ? org.apache.drill.common.types.TypeProtos.MinorType.LATE : result;
      }
      /**
       * <code>optional .common.MinorType minor_type = 1;</code>
       * @param value The minorType to set.
       * @return This builder for chaining.
       */
      public Builder setMinorType(org.apache.drill.common.types.TypeProtos.MinorType value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000001;
        minorType_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .common.MinorType minor_type = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearMinorType() {
        bitField0_ = (bitField0_ & ~0x00000001);
        minorType_ = 0;
        onChanged();
        return this;
      }

      private int mode_ = 0;
      /**
       * <code>optional .common.DataMode mode = 2;</code>
       * @return Whether the mode field is set.
       */
      @java.lang.Override public boolean hasMode() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional .common.DataMode mode = 2;</code>
       * @return The mode.
       */
      @java.lang.Override
      public org.apache.drill.common.types.TypeProtos.DataMode getMode() {
        @SuppressWarnings("deprecation")
        org.apache.drill.common.types.TypeProtos.DataMode result = org.apache.drill.common.types.TypeProtos.DataMode.valueOf(mode_);
        return result == null ? org.apache.drill.common.types.TypeProtos.DataMode.OPTIONAL : result;
      }
      /**
       * <code>optional .common.DataMode mode = 2;</code>
       * @param value The mode to set.
       * @return This builder for chaining.
       */
      public Builder setMode(org.apache.drill.common.types.TypeProtos.DataMode value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000002;
        mode_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .common.DataMode mode = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearMode() {
        bitField0_ = (bitField0_ & ~0x00000002);
        mode_ = 0;
        onChanged();
        return this;
      }

      private int width_ ;
      /**
       * <code>optional int32 width = 3;</code>
       * @return Whether the width field is set.
       */
      @java.lang.Override
      public boolean hasWidth() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional int32 width = 3;</code>
       * @return The width.
       */
      @java.lang.Override
      public int getWidth() {
        return width_;
      }
      /**
       * <code>optional int32 width = 3;</code>
       * @param value The width to set.
       * @return This builder for chaining.
       */
      public Builder setWidth(int value) {
        bitField0_ |= 0x00000004;
        width_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 width = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearWidth() {
        bitField0_ = (bitField0_ & ~0x00000004);
        width_ = 0;
        onChanged();
        return this;
      }

      private int precision_ ;
      /**
       * <pre>
       * used for decimal types or as optional length for fixed size value
       * </pre>
       *
       * <code>optional int32 precision = 4;</code>
       * @return Whether the precision field is set.
       */
      @java.lang.Override
      public boolean hasPrecision() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <pre>
       * used for decimal types or as optional length for fixed size value
       * </pre>
       *
       * <code>optional int32 precision = 4;</code>
       * @return The precision.
       */
      @java.lang.Override
      public int getPrecision() {
        return precision_;
      }
      /**
       * <pre>
       * used for decimal types or as optional length for fixed size value
       * </pre>
       *
       * <code>optional int32 precision = 4;</code>
       * @param value The precision to set.
       * @return This builder for chaining.
       */
      public Builder setPrecision(int value) {
        bitField0_ |= 0x00000008;
        precision_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * used for decimal types or as optional length for fixed size value
       * </pre>
       *
       * <code>optional int32 precision = 4;</code>
       * @return This builder for chaining.
       */
      public Builder clearPrecision() {
        bitField0_ = (bitField0_ & ~0x00000008);
        precision_ = 0;
        onChanged();
        return this;
      }

      private int scale_ ;
      /**
       * <pre>
       * used for decimal types
       * </pre>
       *
       * <code>optional int32 scale = 5;</code>
       * @return Whether the scale field is set.
       */
      @java.lang.Override
      public boolean hasScale() {
        return ((bitField0_ & 0x00000010) != 0);
      }
      /**
       * <pre>
       * used for decimal types
       * </pre>
       *
       * <code>optional int32 scale = 5;</code>
       * @return The scale.
       */
      @java.lang.Override
      public int getScale() {
        return scale_;
      }
      /**
       * <pre>
       * used for decimal types
       * </pre>
       *
       * <code>optional int32 scale = 5;</code>
       * @param value The scale to set.
       * @return This builder for chaining.
       */
      public Builder setScale(int value) {
        bitField0_ |= 0x00000010;
        scale_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * used for decimal types
       * </pre>
       *
       * <code>optional int32 scale = 5;</code>
       * @return This builder for chaining.
       */
      public Builder clearScale() {
        bitField0_ = (bitField0_ & ~0x00000010);
        scale_ = 0;
        onChanged();
        return this;
      }

      private int timeZone_ ;
      /**
       * <pre>
       * used by TimeStamp type
       * </pre>
       *
       * <code>optional int32 timeZone = 6;</code>
       * @return Whether the timeZone field is set.
       */
      @java.lang.Override
      public boolean hasTimeZone() {
        return ((bitField0_ & 0x00000020) != 0);
      }
      /**
       * <pre>
       * used by TimeStamp type
       * </pre>
       *
       * <code>optional int32 timeZone = 6;</code>
       * @return The timeZone.
       */
      @java.lang.Override
      public int getTimeZone() {
        return timeZone_;
      }
      /**
       * <pre>
       * used by TimeStamp type
       * </pre>
       *
       * <code>optional int32 timeZone = 6;</code>
       * @param value The timeZone to set.
       * @return This builder for chaining.
       */
      public Builder setTimeZone(int value) {
        bitField0_ |= 0x00000020;
        timeZone_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * used by TimeStamp type
       * </pre>
       *
       * <code>optional int32 timeZone = 6;</code>
       * @return This builder for chaining.
       */
      public Builder clearTimeZone() {
        bitField0_ = (bitField0_ & ~0x00000020);
        timeZone_ = 0;
        onChanged();
        return this;
      }

      private java.util.List<java.lang.Integer> subType_ =
        java.util.Collections.emptyList();
      private void ensureSubTypeIsMutable() {
        if (!((bitField0_ & 0x00000040) != 0)) {
          subType_ = new java.util.ArrayList<java.lang.Integer>(subType_);
          bitField0_ |= 0x00000040;
        }
      }
      /**
       * <pre>
       * used by Union type
       * </pre>
       *
       * <code>repeated .common.MinorType sub_type = 7;</code>
       * @return A list containing the subType.
       */
      public java.util.List<org.apache.drill.common.types.TypeProtos.MinorType> getSubTypeList() {
        return new com.google.protobuf.Internal.ListAdapter<
            java.lang.Integer, org.apache.drill.common.types.TypeProtos.MinorType>(subType_, subType_converter_);
      }
      /**
       * <pre>
       * used by Union type
       * </pre>
       *
       * <code>repeated .common.MinorType sub_type = 7;</code>
       * @return The count of subType.
       */
      public int getSubTypeCount() {
        return subType_.size();
      }
      /**
       * <pre>
       * used by Union type
       * </pre>
       *
       * <code>repeated .common.MinorType sub_type = 7;</code>
       * @param index The index of the element to return.
       * @return The subType at the given index.
       */
      public org.apache.drill.common.types.TypeProtos.MinorType getSubType(int index) {
        return subType_converter_.convert(subType_.get(index));
      }
      /**
       * <pre>
       * used by Union type
       * </pre>
       *
       * <code>repeated .common.MinorType sub_type = 7;</code>
       * @param index The index to set the value at.
       * @param value The subType to set.
       * @return This builder for chaining.
       */
      public Builder setSubType(
          int index, org.apache.drill.common.types.TypeProtos.MinorType value) {
        if (value == null) {
          throw new NullPointerException();
        }
        ensureSubTypeIsMutable();
        subType_.set(index, value.getNumber());
        onChanged();
        return this;
      }
      /**
       * <pre>
       * used by Union type
       * </pre>
       *
       * <code>repeated .common.MinorType sub_type = 7;</code>
       * @param value The subType to add.
       * @return This builder for chaining.
       */
      public Builder addSubType(org.apache.drill.common.types.TypeProtos.MinorType value) {
        if (value == null) {
          throw new NullPointerException();
        }
        ensureSubTypeIsMutable();
        subType_.add(value.getNumber());
        onChanged();
        return this;
      }
      /**
       * <pre>
       * used by Union type
       * </pre>
       *
       * <code>repeated .common.MinorType sub_type = 7;</code>
       * @param values The subType to add.
       * @return This builder for chaining.
       */
      public Builder addAllSubType(
          java.lang.Iterable<? extends org.apache.drill.common.types.TypeProtos.MinorType> values) {
        ensureSubTypeIsMutable();
        for (org.apache.drill.common.types.TypeProtos.MinorType value : values) {
          subType_.add(value.getNumber());
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * used by Union type
       * </pre>
       *
       * <code>repeated .common.MinorType sub_type = 7;</code>
       * @return This builder for chaining.
       */
      public Builder clearSubType() {
        subType_ = java.util.Collections.emptyList();
        bitField0_ = (bitField0_ & ~0x00000040);
        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:common.MajorType)
    }

    // @@protoc_insertion_point(class_scope:common.MajorType)
    private static final org.apache.drill.common.types.TypeProtos.MajorType DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.common.types.TypeProtos.MajorType();
    }

    public static org.apache.drill.common.types.TypeProtos.MajorType getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<MajorType>
        PARSER = new com.google.protobuf.AbstractParser<MajorType>() {
      @java.lang.Override
      public MajorType 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<MajorType> parser() {
      return PARSER;
    }

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

    @java.lang.Override
    public org.apache.drill.common.types.TypeProtos.MajorType getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_common_MajorType_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_common_MajorType_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\013Types.proto\022\006common\"\272\001\n\tMajorType\022%\n\nm" +
      "inor_type\030\001 \001(\0162\021.common.MinorType\022\036\n\004mo" +
      "de\030\002 \001(\0162\020.common.DataMode\022\r\n\005width\030\003 \001(" +
      "\005\022\021\n\tprecision\030\004 \001(\005\022\r\n\005scale\030\005 \001(\005\022\020\n\010t" +
      "imeZone\030\006 \001(\005\022#\n\010sub_type\030\007 \003(\0162\021.common" +
      ".MinorType*\257\004\n\tMinorType\022\010\n\004LATE\020\000\022\007\n\003MA" +
      "P\020\001\022\013\n\007TINYINT\020\003\022\014\n\010SMALLINT\020\004\022\007\n\003INT\020\005\022" +
      "\n\n\006BIGINT\020\006\022\014\n\010DECIMAL9\020\007\022\r\n\tDECIMAL18\020\010" +
      "\022\023\n\017DECIMAL28SPARSE\020\t\022\023\n\017DECIMAL38SPARSE" +
      "\020\n\022\t\n\005MONEY\020\013\022\010\n\004DATE\020\014\022\010\n\004TIME\020\r\022\n\n\006TIM" +
      "ETZ\020\016\022\017\n\013TIMESTAMPTZ\020\017\022\r\n\tTIMESTAMP\020\020\022\014\n" +
      "\010INTERVAL\020\021\022\n\n\006FLOAT4\020\022\022\n\n\006FLOAT8\020\023\022\007\n\003B" +
      "IT\020\024\022\r\n\tFIXEDCHAR\020\025\022\017\n\013FIXED16CHAR\020\026\022\017\n\013" +
      "FIXEDBINARY\020\027\022\013\n\007VARCHAR\020\030\022\r\n\tVAR16CHAR\020" +
      "\031\022\r\n\tVARBINARY\020\032\022\t\n\005UINT1\020\035\022\t\n\005UINT2\020\036\022\t" +
      "\n\005UINT4\020\037\022\t\n\005UINT8\020 \022\022\n\016DECIMAL28DENSE\020!" +
      "\022\022\n\016DECIMAL38DENSE\020\"\022\010\n\004NULL\020%\022\020\n\014INTERV" +
      "ALYEAR\020&\022\017\n\013INTERVALDAY\020\'\022\010\n\004LIST\020(\022\022\n\016G" +
      "ENERIC_OBJECT\020)\022\t\n\005UNION\020*\022\016\n\nVARDECIMAL" +
      "\020+\022\010\n\004DICT\020,*4\n\010DataMode\022\014\n\010OPTIONAL\020\000\022\014" +
      "\n\010REQUIRED\020\001\022\014\n\010REPEATED\020\002B-\n\035org.apache" +
      ".drill.common.typesB\nTypeProtosH\001"
    };
    descriptor = com.google.protobuf.Descriptors.FileDescriptor
      .internalBuildGeneratedFileFrom(descriptorData,
        new com.google.protobuf.Descriptors.FileDescriptor[] {
        });
    internal_static_common_MajorType_descriptor =
      getDescriptor().getMessageTypes().get(0);
    internal_static_common_MajorType_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_common_MajorType_descriptor,
        new java.lang.String[] { "MinorType", "Mode", "Width", "Precision", "Scale", "TimeZone", "SubType", });
  }

  // @@protoc_insertion_point(outer_class_scope)
}
