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

package org.apache.druid.data.input.protobuf;

@SuppressWarnings("ALL")
public final class ProtoTestEventWrapper {
  private ProtoTestEventWrapper() {}
  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistryLite registry) {
  }

  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistry registry) {
    registerAllExtensions(
        (com.google.protobuf.ExtensionRegistryLite) registry);
  }
  public interface ProtoTestEventOrBuilder extends
      // @@protoc_insertion_point(interface_extends:prototest.ProtoTestEvent)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>required .prototest.ProtoTestEvent.EventCategory eventType = 1;</code>
     * @return Whether the eventType field is set.
     */
    boolean hasEventType();
    /**
     * <code>required .prototest.ProtoTestEvent.EventCategory eventType = 1;</code>
     * @return The eventType.
     */
    org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.EventCategory getEventType();

    /**
     * <code>required uint64 id = 2;</code>
     * @return Whether the id field is set.
     */
    boolean hasId();
    /**
     * <code>required uint64 id = 2;</code>
     * @return The id.
     */
    long getId();

    /**
     * <code>required string timestamp = 3;</code>
     * @return Whether the timestamp field is set.
     */
    boolean hasTimestamp();
    /**
     * <code>required string timestamp = 3;</code>
     * @return The timestamp.
     */
    java.lang.String getTimestamp();
    /**
     * <code>required string timestamp = 3;</code>
     * @return The bytes for timestamp.
     */
    com.google.protobuf.ByteString
        getTimestampBytes();

    /**
     * <code>optional uint32 someOtherId = 4;</code>
     * @return Whether the someOtherId field is set.
     */
    boolean hasSomeOtherId();
    /**
     * <code>optional uint32 someOtherId = 4;</code>
     * @return The someOtherId.
     */
    int getSomeOtherId();

    /**
     * <code>optional bool isValid = 5;</code>
     * @return Whether the isValid field is set.
     */
    boolean hasIsValid();
    /**
     * <code>optional bool isValid = 5;</code>
     * @return The isValid.
     */
    boolean getIsValid();

    /**
     * <code>optional string description = 6;</code>
     * @return Whether the description field is set.
     */
    boolean hasDescription();
    /**
     * <code>optional string description = 6;</code>
     * @return The description.
     */
    java.lang.String getDescription();
    /**
     * <code>optional string description = 6;</code>
     * @return The bytes for description.
     */
    com.google.protobuf.ByteString
        getDescriptionBytes();

    /**
     * <code>optional float someFloatColumn = 7;</code>
     * @return Whether the someFloatColumn field is set.
     */
    boolean hasSomeFloatColumn();
    /**
     * <code>optional float someFloatColumn = 7;</code>
     * @return The someFloatColumn.
     */
    float getSomeFloatColumn();

    /**
     * <code>optional uint32 someIntColumn = 8;</code>
     * @return Whether the someIntColumn field is set.
     */
    boolean hasSomeIntColumn();
    /**
     * <code>optional uint32 someIntColumn = 8;</code>
     * @return The someIntColumn.
     */
    int getSomeIntColumn();

    /**
     * <code>optional uint64 someLongColumn = 9;</code>
     * @return Whether the someLongColumn field is set.
     */
    boolean hasSomeLongColumn();
    /**
     * <code>optional uint64 someLongColumn = 9;</code>
     * @return The someLongColumn.
     */
    long getSomeLongColumn();

    /**
     * <code>optional .prototest.ProtoTestEvent.Foo foo = 10;</code>
     * @return Whether the foo field is set.
     */
    boolean hasFoo();
    /**
     * <code>optional .prototest.ProtoTestEvent.Foo foo = 10;</code>
     * @return The foo.
     */
    org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo getFoo();
    /**
     * <code>optional .prototest.ProtoTestEvent.Foo foo = 10;</code>
     */
    org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.FooOrBuilder getFooOrBuilder();

    /**
     * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
     */
    java.util.List<org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo> 
        getBarList();
    /**
     * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
     */
    org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo getBar(int index);
    /**
     * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
     */
    int getBarCount();
    /**
     * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
     */
    java.util.List<? extends org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.FooOrBuilder> 
        getBarOrBuilderList();
    /**
     * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
     */
    org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.FooOrBuilder getBarOrBuilder(
        int index);

    /**
     * <code>optional .google.protobuf.Timestamp otherTimestamp = 12;</code>
     * @return Whether the otherTimestamp field is set.
     */
    boolean hasOtherTimestamp();
    /**
     * <code>optional .google.protobuf.Timestamp otherTimestamp = 12;</code>
     * @return The otherTimestamp.
     */
    com.google.protobuf.Timestamp getOtherTimestamp();
    /**
     * <code>optional .google.protobuf.Timestamp otherTimestamp = 12;</code>
     */
    com.google.protobuf.TimestampOrBuilder getOtherTimestampOrBuilder();
  }
  /**
   * Protobuf type {@code prototest.ProtoTestEvent}
   */
  public static final class ProtoTestEvent extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:prototest.ProtoTestEvent)
      ProtoTestEventOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use ProtoTestEvent.newBuilder() to construct.
    private ProtoTestEvent(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private ProtoTestEvent() {
      eventType_ = 0;
      timestamp_ = "";
      description_ = "";
      bar_ = java.util.Collections.emptyList();
    }

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

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    private ProtoTestEvent(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      this();
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 8: {
              int rawValue = input.readEnum();
                @SuppressWarnings("deprecation")
              org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.EventCategory value = org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.EventCategory.valueOf(rawValue);
              if (value == null) {
                unknownFields.mergeVarintField(1, rawValue);
              } else {
                bitField0_ |= 0x00000001;
                eventType_ = rawValue;
              }
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              id_ = input.readUInt64();
              break;
            }
            case 26: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00000004;
              timestamp_ = bs;
              break;
            }
            case 32: {
              bitField0_ |= 0x00000008;
              someOtherId_ = input.readUInt32();
              break;
            }
            case 40: {
              bitField0_ |= 0x00000010;
              isValid_ = input.readBool();
              break;
            }
            case 50: {
              com.google.protobuf.ByteString bs = input.readBytes();
              bitField0_ |= 0x00000020;
              description_ = bs;
              break;
            }
            case 61: {
              bitField0_ |= 0x00000040;
              someFloatColumn_ = input.readFloat();
              break;
            }
            case 64: {
              bitField0_ |= 0x00000080;
              someIntColumn_ = input.readUInt32();
              break;
            }
            case 72: {
              bitField0_ |= 0x00000100;
              someLongColumn_ = input.readUInt64();
              break;
            }
            case 82: {
              org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.Builder subBuilder = null;
              if (((bitField0_ & 0x00000200) != 0)) {
                subBuilder = foo_.toBuilder();
              }
              foo_ = input.readMessage(org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.PARSER, extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(foo_);
                foo_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000200;
              break;
            }
            case 90: {
              if (!((mutable_bitField0_ & 0x00000400) != 0)) {
                bar_ = new java.util.ArrayList<org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo>();
                mutable_bitField0_ |= 0x00000400;
              }
              bar_.add(
                  input.readMessage(org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.PARSER, extensionRegistry));
              break;
            }
            case 98: {
              com.google.protobuf.Timestamp.Builder subBuilder = null;
              if (((bitField0_ & 0x00000400) != 0)) {
                subBuilder = otherTimestamp_.toBuilder();
              }
              otherTimestamp_ = input.readMessage(com.google.protobuf.Timestamp.parser(), extensionRegistry);
              if (subBuilder != null) {
                subBuilder.mergeFrom(otherTimestamp_);
                otherTimestamp_ = subBuilder.buildPartial();
              }
              bitField0_ |= 0x00000400;
              break;
            }
            default: {
              if (!parseUnknownField(
                  input, unknownFields, extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000400) != 0)) {
          bar_ = java.util.Collections.unmodifiableList(bar_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.internal_static_prototest_ProtoTestEvent_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.internal_static_prototest_ProtoTestEvent_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.class, org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Builder.class);
    }

    /**
     * Protobuf enum {@code prototest.ProtoTestEvent.EventCategory}
     */
    public enum EventCategory
        implements com.google.protobuf.ProtocolMessageEnum {
      /**
       * <code>CATEGORY_ZERO = 0;</code>
       */
      CATEGORY_ZERO(0),
      /**
       * <code>CATEGORY_ONE = 1;</code>
       */
      CATEGORY_ONE(1),
      /**
       * <code>CATEGORY_TWO = 2;</code>
       */
      CATEGORY_TWO(2),
      ;

      /**
       * <code>CATEGORY_ZERO = 0;</code>
       */
      public static final int CATEGORY_ZERO_VALUE = 0;
      /**
       * <code>CATEGORY_ONE = 1;</code>
       */
      public static final int CATEGORY_ONE_VALUE = 1;
      /**
       * <code>CATEGORY_TWO = 2;</code>
       */
      public static final int CATEGORY_TWO_VALUE = 2;


      @Override
      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 EventCategory 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 EventCategory forNumber(int value) {
        switch (value) {
          case 0: return CATEGORY_ZERO;
          case 1: return CATEGORY_ONE;
          case 2: return CATEGORY_TWO;
          default: return null;
        }
      }

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

      @Override
      public final com.google.protobuf.Descriptors.EnumValueDescriptor
          getValueDescriptor() {
        return getDescriptor().getValues().get(ordinal());
      }
      @Override
      public final com.google.protobuf.Descriptors.EnumDescriptor
          getDescriptorForType() {
        return getDescriptor();
      }
      public static final com.google.protobuf.Descriptors.EnumDescriptor
          getDescriptor() {
        return org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.getDescriptor().getEnumTypes().get(0);
      }

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

      public static EventCategory 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;

      EventCategory(int value) {
        this.value = value;
      }

      // @@protoc_insertion_point(enum_scope:prototest.ProtoTestEvent.EventCategory)
    }

    public interface FooOrBuilder extends
        // @@protoc_insertion_point(interface_extends:prototest.ProtoTestEvent.Foo)
        com.google.protobuf.MessageOrBuilder {

      /**
       * <code>required string bar = 1;</code>
       * @return Whether the bar field is set.
       */
      boolean hasBar();
      /**
       * <code>required string bar = 1;</code>
       * @return The bar.
       */
      java.lang.String getBar();
      /**
       * <code>required string bar = 1;</code>
       * @return The bytes for bar.
       */
      com.google.protobuf.ByteString
          getBarBytes();
    }
    /**
     * Protobuf type {@code prototest.ProtoTestEvent.Foo}
     */
    public static final class Foo extends
        com.google.protobuf.GeneratedMessageV3 implements
        // @@protoc_insertion_point(message_implements:prototest.ProtoTestEvent.Foo)
        FooOrBuilder {
    private static final long serialVersionUID = 0L;
      // Use Foo.newBuilder() to construct.
      private Foo(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
        super(builder);
      }
      private Foo() {
        bar_ = "";
      }

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

      @Override
      public final com.google.protobuf.UnknownFieldSet
      getUnknownFields() {
        return this.unknownFields;
      }
      private Foo(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        this();
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        int mutable_bitField0_ = 0;
        com.google.protobuf.UnknownFieldSet.Builder unknownFields =
            com.google.protobuf.UnknownFieldSet.newBuilder();
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                com.google.protobuf.ByteString bs = input.readBytes();
                bitField0_ |= 0x00000001;
                bar_ = bs;
                break;
              }
              default: {
                if (!parseUnknownField(
                    input, unknownFields, extensionRegistry, tag)) {
                  done = true;
                }
                break;
              }
            }
          }
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(this);
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(
              e).setUnfinishedMessage(this);
        } finally {
          this.unknownFields = unknownFields.build();
          makeExtensionsImmutable();
        }
      }
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.internal_static_prototest_ProtoTestEvent_Foo_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.internal_static_prototest_ProtoTestEvent_Foo_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.class, org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.Builder.class);
      }

      private int bitField0_;
      public static final int BAR_FIELD_NUMBER = 1;
      private volatile java.lang.Object bar_;
      /**
       * <code>required string bar = 1;</code>
       * @return Whether the bar field is set.
       */
      @Override
      public boolean hasBar() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>required string bar = 1;</code>
       * @return The bar.
       */
      @Override
      public java.lang.String getBar() {
        java.lang.Object ref = bar_;
        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()) {
            bar_ = s;
          }
          return s;
        }
      }
      /**
       * <code>required string bar = 1;</code>
       * @return The bytes for bar.
       */
      @Override
      public com.google.protobuf.ByteString
          getBarBytes() {
        java.lang.Object ref = bar_;
        if (ref instanceof java.lang.String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          bar_ = 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;

        if (!hasBar()) {
          memoizedIsInitialized = 0;
          return false;
        }
        memoizedIsInitialized = 1;
        return true;
      }

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

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

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

      @Override
      public boolean equals(final java.lang.Object obj) {
        if (obj == this) {
         return true;
        }
        if (!(obj instanceof org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo)) {
          return super.equals(obj);
        }
        org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo other = (org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo) obj;

        if (hasBar() != other.hasBar()) return false;
        if (hasBar()) {
          if (!getBar()
              .equals(other.getBar())) return false;
        }
        if (!unknownFields.equals(other.unknownFields)) return false;
        return true;
      }

      @Override
      public int hashCode() {
        if (memoizedHashCode != 0) {
          return memoizedHashCode;
        }
        int hash = 41;
        hash = (19 * hash) + getDescriptor().hashCode();
        if (hasBar()) {
          hash = (37 * hash) + BAR_FIELD_NUMBER;
          hash = (53 * hash) + getBar().hashCode();
        }
        hash = (29 * hash) + unknownFields.hashCode();
        memoizedHashCode = hash;
        return hash;
      }

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

        @java.lang.Override
        protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
            internalGetFieldAccessorTable() {
          return org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.internal_static_prototest_ProtoTestEvent_Foo_fieldAccessorTable
              .ensureFieldAccessorsInitialized(
                  org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.class, org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.Builder.class);
        }

        // Construct using org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.newBuilder()
        private Builder() {
          maybeForceBuilderInitialization();
        }

        private Builder(
            com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
          super(parent);
          maybeForceBuilderInitialization();
        }
        private void maybeForceBuilderInitialization() {
          if (com.google.protobuf.GeneratedMessageV3
                  .alwaysUseFieldBuilders) {
          }
        }
        @Override
        public Builder clear() {
          super.clear();
          bar_ = "";
          bitField0_ = (bitField0_ & ~0x00000001);
          return this;
        }

        @Override
        public com.google.protobuf.Descriptors.Descriptor
            getDescriptorForType() {
          return org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.internal_static_prototest_ProtoTestEvent_Foo_descriptor;
        }

        @Override
        public org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo getDefaultInstanceForType() {
          return org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.getDefaultInstance();
        }

        @Override
        public org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo build() {
          org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo result = buildPartial();
          if (!result.isInitialized()) {
            throw newUninitializedMessageException(result);
          }
          return result;
        }

        @Override
        public org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo buildPartial() {
          org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo result = new org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo(this);
          int from_bitField0_ = bitField0_;
          int to_bitField0_ = 0;
          if (((from_bitField0_ & 0x00000001) != 0)) {
            to_bitField0_ |= 0x00000001;
          }
          result.bar_ = bar_;
          result.bitField0_ = to_bitField0_;
          onBuilt();
          return result;
        }

        @Override
        public Builder clone() {
          return super.clone();
        }
        @Override
        public Builder setField(
            com.google.protobuf.Descriptors.FieldDescriptor field,
            java.lang.Object value) {
          return super.setField(field, value);
        }
        @Override
        public Builder clearField(
            com.google.protobuf.Descriptors.FieldDescriptor field) {
          return super.clearField(field);
        }
        @Override
        public Builder clearOneof(
            com.google.protobuf.Descriptors.OneofDescriptor oneof) {
          return super.clearOneof(oneof);
        }
        @Override
        public Builder setRepeatedField(
            com.google.protobuf.Descriptors.FieldDescriptor field,
            int index, java.lang.Object value) {
          return super.setRepeatedField(field, index, value);
        }
        @Override
        public Builder addRepeatedField(
            com.google.protobuf.Descriptors.FieldDescriptor field,
            java.lang.Object value) {
          return super.addRepeatedField(field, value);
        }
        @Override
        public Builder mergeFrom(com.google.protobuf.Message other) {
          if (other instanceof org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo) {
            return mergeFrom((org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo)other);
          } else {
            super.mergeFrom(other);
            return this;
          }
        }

        public Builder mergeFrom(org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo other) {
          if (other == org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.getDefaultInstance()) return this;
          if (other.hasBar()) {
            bitField0_ |= 0x00000001;
            bar_ = other.bar_;
            onChanged();
          }
          this.mergeUnknownFields(other.unknownFields);
          onChanged();
          return this;
        }

        @Override
        public final boolean isInitialized() {
          if (!hasBar()) {
            return false;
          }
          return true;
        }

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

        private java.lang.Object bar_ = "";
        /**
         * <code>required string bar = 1;</code>
         * @return Whether the bar field is set.
         */
        @Override
        public boolean hasBar() {
          return ((bitField0_ & 0x00000001) != 0);
        }
        /**
         * <code>required string bar = 1;</code>
         * @return The bar.
         */
        @Override
        public java.lang.String getBar() {
          java.lang.Object ref = bar_;
          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()) {
              bar_ = s;
            }
            return s;
          } else {
            return (java.lang.String) ref;
          }
        }
        /**
         * <code>required string bar = 1;</code>
         * @return The bytes for bar.
         */
        @Override
        public com.google.protobuf.ByteString
            getBarBytes() {
          java.lang.Object ref = bar_;
          if (ref instanceof String) {
            com.google.protobuf.ByteString b = 
                com.google.protobuf.ByteString.copyFromUtf8(
                    (java.lang.String) ref);
            bar_ = b;
            return b;
          } else {
            return (com.google.protobuf.ByteString) ref;
          }
        }
        /**
         * <code>required string bar = 1;</code>
         * @param value The bar to set.
         * @return This builder for chaining.
         */
        public Builder setBar(
            java.lang.String value) {
          if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
          bar_ = value;
          onChanged();
          return this;
        }
        /**
         * <code>required string bar = 1;</code>
         * @return This builder for chaining.
         */
        public Builder clearBar() {
          bitField0_ = (bitField0_ & ~0x00000001);
          bar_ = getDefaultInstance().getBar();
          onChanged();
          return this;
        }
        /**
         * <code>required string bar = 1;</code>
         * @param value The bytes for bar to set.
         * @return This builder for chaining.
         */
        public Builder setBarBytes(
            com.google.protobuf.ByteString value) {
          if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
          bar_ = value;
          onChanged();
          return this;
        }
        @Override
        public final Builder setUnknownFields(
            final com.google.protobuf.UnknownFieldSet unknownFields) {
          return super.setUnknownFields(unknownFields);
        }

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


        // @@protoc_insertion_point(builder_scope:prototest.ProtoTestEvent.Foo)
      }

      // @@protoc_insertion_point(class_scope:prototest.ProtoTestEvent.Foo)
      private static final org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo DEFAULT_INSTANCE;
      static {
        DEFAULT_INSTANCE = new org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo();
      }

      public static org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo getDefaultInstance() {
        return DEFAULT_INSTANCE;
      }

      @java.lang.Deprecated public static final com.google.protobuf.Parser<Foo>
          PARSER = new com.google.protobuf.AbstractParser<Foo>() {
        @Override
        public Foo parsePartialFrom(
            com.google.protobuf.CodedInputStream input,
            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
            throws com.google.protobuf.InvalidProtocolBufferException {
          return new Foo(input, extensionRegistry);
        }
      };

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

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

      @Override
      public org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo getDefaultInstanceForType() {
        return DEFAULT_INSTANCE;
      }

    }

    private int bitField0_;
    public static final int EVENTTYPE_FIELD_NUMBER = 1;
    private int eventType_;
    /**
     * <code>required .prototest.ProtoTestEvent.EventCategory eventType = 1;</code>
     * @return Whether the eventType field is set.
     */
    @Override public boolean hasEventType() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>required .prototest.ProtoTestEvent.EventCategory eventType = 1;</code>
     * @return The eventType.
     */
    @Override public org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.EventCategory getEventType() {
      @SuppressWarnings("deprecation")
      org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.EventCategory result = org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.EventCategory.valueOf(eventType_);
      return result == null ? org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.EventCategory.CATEGORY_ZERO : result;
    }

    public static final int ID_FIELD_NUMBER = 2;
    private long id_;
    /**
     * <code>required uint64 id = 2;</code>
     * @return Whether the id field is set.
     */
    @Override
    public boolean hasId() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>required uint64 id = 2;</code>
     * @return The id.
     */
    @Override
    public long getId() {
      return id_;
    }

    public static final int TIMESTAMP_FIELD_NUMBER = 3;
    private volatile java.lang.Object timestamp_;
    /**
     * <code>required string timestamp = 3;</code>
     * @return Whether the timestamp field is set.
     */
    @Override
    public boolean hasTimestamp() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>required string timestamp = 3;</code>
     * @return The timestamp.
     */
    @Override
    public java.lang.String getTimestamp() {
      java.lang.Object ref = timestamp_;
      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()) {
          timestamp_ = s;
        }
        return s;
      }
    }
    /**
     * <code>required string timestamp = 3;</code>
     * @return The bytes for timestamp.
     */
    @Override
    public com.google.protobuf.ByteString
        getTimestampBytes() {
      java.lang.Object ref = timestamp_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        timestamp_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int SOMEOTHERID_FIELD_NUMBER = 4;
    private int someOtherId_;
    /**
     * <code>optional uint32 someOtherId = 4;</code>
     * @return Whether the someOtherId field is set.
     */
    @Override
    public boolean hasSomeOtherId() {
      return ((bitField0_ & 0x00000008) != 0);
    }
    /**
     * <code>optional uint32 someOtherId = 4;</code>
     * @return The someOtherId.
     */
    @Override
    public int getSomeOtherId() {
      return someOtherId_;
    }

    public static final int ISVALID_FIELD_NUMBER = 5;
    private boolean isValid_;
    /**
     * <code>optional bool isValid = 5;</code>
     * @return Whether the isValid field is set.
     */
    @Override
    public boolean hasIsValid() {
      return ((bitField0_ & 0x00000010) != 0);
    }
    /**
     * <code>optional bool isValid = 5;</code>
     * @return The isValid.
     */
    @Override
    public boolean getIsValid() {
      return isValid_;
    }

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

    public static final int SOMEFLOATCOLUMN_FIELD_NUMBER = 7;
    private float someFloatColumn_;
    /**
     * <code>optional float someFloatColumn = 7;</code>
     * @return Whether the someFloatColumn field is set.
     */
    @Override
    public boolean hasSomeFloatColumn() {
      return ((bitField0_ & 0x00000040) != 0);
    }
    /**
     * <code>optional float someFloatColumn = 7;</code>
     * @return The someFloatColumn.
     */
    @Override
    public float getSomeFloatColumn() {
      return someFloatColumn_;
    }

    public static final int SOMEINTCOLUMN_FIELD_NUMBER = 8;
    private int someIntColumn_;
    /**
     * <code>optional uint32 someIntColumn = 8;</code>
     * @return Whether the someIntColumn field is set.
     */
    @Override
    public boolean hasSomeIntColumn() {
      return ((bitField0_ & 0x00000080) != 0);
    }
    /**
     * <code>optional uint32 someIntColumn = 8;</code>
     * @return The someIntColumn.
     */
    @Override
    public int getSomeIntColumn() {
      return someIntColumn_;
    }

    public static final int SOMELONGCOLUMN_FIELD_NUMBER = 9;
    private long someLongColumn_;
    /**
     * <code>optional uint64 someLongColumn = 9;</code>
     * @return Whether the someLongColumn field is set.
     */
    @Override
    public boolean hasSomeLongColumn() {
      return ((bitField0_ & 0x00000100) != 0);
    }
    /**
     * <code>optional uint64 someLongColumn = 9;</code>
     * @return The someLongColumn.
     */
    @Override
    public long getSomeLongColumn() {
      return someLongColumn_;
    }

    public static final int FOO_FIELD_NUMBER = 10;
    private org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo foo_;
    /**
     * <code>optional .prototest.ProtoTestEvent.Foo foo = 10;</code>
     * @return Whether the foo field is set.
     */
    @Override
    public boolean hasFoo() {
      return ((bitField0_ & 0x00000200) != 0);
    }
    /**
     * <code>optional .prototest.ProtoTestEvent.Foo foo = 10;</code>
     * @return The foo.
     */
    @Override
    public org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo getFoo() {
      return foo_ == null ? org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.getDefaultInstance() : foo_;
    }
    /**
     * <code>optional .prototest.ProtoTestEvent.Foo foo = 10;</code>
     */
    @Override
    public org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.FooOrBuilder getFooOrBuilder() {
      return foo_ == null ? org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.getDefaultInstance() : foo_;
    }

    public static final int BAR_FIELD_NUMBER = 11;
    private java.util.List<org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo> bar_;
    /**
     * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
     */
    @Override
    public java.util.List<org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo> getBarList() {
      return bar_;
    }
    /**
     * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
     */
    @Override
    public java.util.List<? extends org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.FooOrBuilder> 
        getBarOrBuilderList() {
      return bar_;
    }
    /**
     * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
     */
    @Override
    public int getBarCount() {
      return bar_.size();
    }
    /**
     * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
     */
    @Override
    public org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo getBar(int index) {
      return bar_.get(index);
    }
    /**
     * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
     */
    @Override
    public org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.FooOrBuilder getBarOrBuilder(
        int index) {
      return bar_.get(index);
    }

    public static final int OTHERTIMESTAMP_FIELD_NUMBER = 12;
    private com.google.protobuf.Timestamp otherTimestamp_;
    /**
     * <code>optional .google.protobuf.Timestamp otherTimestamp = 12;</code>
     * @return Whether the otherTimestamp field is set.
     */
    @Override
    public boolean hasOtherTimestamp() {
      return ((bitField0_ & 0x00000400) != 0);
    }
    /**
     * <code>optional .google.protobuf.Timestamp otherTimestamp = 12;</code>
     * @return The otherTimestamp.
     */
    @Override
    public com.google.protobuf.Timestamp getOtherTimestamp() {
      return otherTimestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : otherTimestamp_;
    }
    /**
     * <code>optional .google.protobuf.Timestamp otherTimestamp = 12;</code>
     */
    @Override
    public com.google.protobuf.TimestampOrBuilder getOtherTimestampOrBuilder() {
      return otherTimestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : otherTimestamp_;
    }

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

      if (!hasEventType()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasTimestamp()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (hasFoo()) {
        if (!getFoo().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      for (int i = 0; i < getBarCount(); i++) {
        if (!getBar(i).isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    @Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeEnum(1, eventType_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeUInt64(2, id_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 3, timestamp_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        output.writeUInt32(4, someOtherId_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        output.writeBool(5, isValid_);
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 6, description_);
      }
      if (((bitField0_ & 0x00000040) != 0)) {
        output.writeFloat(7, someFloatColumn_);
      }
      if (((bitField0_ & 0x00000080) != 0)) {
        output.writeUInt32(8, someIntColumn_);
      }
      if (((bitField0_ & 0x00000100) != 0)) {
        output.writeUInt64(9, someLongColumn_);
      }
      if (((bitField0_ & 0x00000200) != 0)) {
        output.writeMessage(10, getFoo());
      }
      for (int i = 0; i < bar_.size(); i++) {
        output.writeMessage(11, bar_.get(i));
      }
      if (((bitField0_ & 0x00000400) != 0)) {
        output.writeMessage(12, getOtherTimestamp());
      }
      unknownFields.writeTo(output);
    }

    @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, eventType_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeUInt64Size(2, id_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, timestamp_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeUInt32Size(4, someOtherId_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(5, isValid_);
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, description_);
      }
      if (((bitField0_ & 0x00000040) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeFloatSize(7, someFloatColumn_);
      }
      if (((bitField0_ & 0x00000080) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeUInt32Size(8, someIntColumn_);
      }
      if (((bitField0_ & 0x00000100) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeUInt64Size(9, someLongColumn_);
      }
      if (((bitField0_ & 0x00000200) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(10, getFoo());
      }
      for (int i = 0; i < bar_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(11, bar_.get(i));
      }
      if (((bitField0_ & 0x00000400) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(12, getOtherTimestamp());
      }
      size += unknownFields.getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent)) {
        return super.equals(obj);
      }
      org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent other = (org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent) obj;

      if (hasEventType() != other.hasEventType()) return false;
      if (hasEventType()) {
        if (eventType_ != other.eventType_) return false;
      }
      if (hasId() != other.hasId()) return false;
      if (hasId()) {
        if (getId()
            != other.getId()) return false;
      }
      if (hasTimestamp() != other.hasTimestamp()) return false;
      if (hasTimestamp()) {
        if (!getTimestamp()
            .equals(other.getTimestamp())) return false;
      }
      if (hasSomeOtherId() != other.hasSomeOtherId()) return false;
      if (hasSomeOtherId()) {
        if (getSomeOtherId()
            != other.getSomeOtherId()) return false;
      }
      if (hasIsValid() != other.hasIsValid()) return false;
      if (hasIsValid()) {
        if (getIsValid()
            != other.getIsValid()) return false;
      }
      if (hasDescription() != other.hasDescription()) return false;
      if (hasDescription()) {
        if (!getDescription()
            .equals(other.getDescription())) return false;
      }
      if (hasSomeFloatColumn() != other.hasSomeFloatColumn()) return false;
      if (hasSomeFloatColumn()) {
        if (java.lang.Float.floatToIntBits(getSomeFloatColumn())
            != java.lang.Float.floatToIntBits(
                other.getSomeFloatColumn())) return false;
      }
      if (hasSomeIntColumn() != other.hasSomeIntColumn()) return false;
      if (hasSomeIntColumn()) {
        if (getSomeIntColumn()
            != other.getSomeIntColumn()) return false;
      }
      if (hasSomeLongColumn() != other.hasSomeLongColumn()) return false;
      if (hasSomeLongColumn()) {
        if (getSomeLongColumn()
            != other.getSomeLongColumn()) return false;
      }
      if (hasFoo() != other.hasFoo()) return false;
      if (hasFoo()) {
        if (!getFoo()
            .equals(other.getFoo())) return false;
      }
      if (!getBarList()
          .equals(other.getBarList())) return false;
      if (hasOtherTimestamp() != other.hasOtherTimestamp()) return false;
      if (hasOtherTimestamp()) {
        if (!getOtherTimestamp()
            .equals(other.getOtherTimestamp())) return false;
      }
      if (!unknownFields.equals(other.unknownFields)) return false;
      return true;
    }

    @Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasEventType()) {
        hash = (37 * hash) + EVENTTYPE_FIELD_NUMBER;
        hash = (53 * hash) + eventType_;
      }
      if (hasId()) {
        hash = (37 * hash) + ID_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getId());
      }
      if (hasTimestamp()) {
        hash = (37 * hash) + TIMESTAMP_FIELD_NUMBER;
        hash = (53 * hash) + getTimestamp().hashCode();
      }
      if (hasSomeOtherId()) {
        hash = (37 * hash) + SOMEOTHERID_FIELD_NUMBER;
        hash = (53 * hash) + getSomeOtherId();
      }
      if (hasIsValid()) {
        hash = (37 * hash) + ISVALID_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getIsValid());
      }
      if (hasDescription()) {
        hash = (37 * hash) + DESCRIPTION_FIELD_NUMBER;
        hash = (53 * hash) + getDescription().hashCode();
      }
      if (hasSomeFloatColumn()) {
        hash = (37 * hash) + SOMEFLOATCOLUMN_FIELD_NUMBER;
        hash = (53 * hash) + java.lang.Float.floatToIntBits(
            getSomeFloatColumn());
      }
      if (hasSomeIntColumn()) {
        hash = (37 * hash) + SOMEINTCOLUMN_FIELD_NUMBER;
        hash = (53 * hash) + getSomeIntColumn();
      }
      if (hasSomeLongColumn()) {
        hash = (37 * hash) + SOMELONGCOLUMN_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
            getSomeLongColumn());
      }
      if (hasFoo()) {
        hash = (37 * hash) + FOO_FIELD_NUMBER;
        hash = (53 * hash) + getFoo().hashCode();
      }
      if (getBarCount() > 0) {
        hash = (37 * hash) + BAR_FIELD_NUMBER;
        hash = (53 * hash) + getBarList().hashCode();
      }
      if (hasOtherTimestamp()) {
        hash = (37 * hash) + OTHERTIMESTAMP_FIELD_NUMBER;
        hash = (53 * hash) + getOtherTimestamp().hashCode();
      }
      hash = (29 * hash) + unknownFields.hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent 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.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent 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.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent 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.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code prototest.ProtoTestEvent}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:prototest.ProtoTestEvent)
        org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEventOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.internal_static_prototest_ProtoTestEvent_descriptor;
      }

      @Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.internal_static_prototest_ProtoTestEvent_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.class, org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Builder.class);
      }

      // Construct using org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getFooFieldBuilder();
          getBarFieldBuilder();
          getOtherTimestampFieldBuilder();
        }
      }
      @Override
      public Builder clear() {
        super.clear();
        eventType_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        id_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        timestamp_ = "";
        bitField0_ = (bitField0_ & ~0x00000004);
        someOtherId_ = 0;
        bitField0_ = (bitField0_ & ~0x00000008);
        isValid_ = false;
        bitField0_ = (bitField0_ & ~0x00000010);
        description_ = "";
        bitField0_ = (bitField0_ & ~0x00000020);
        someFloatColumn_ = 0F;
        bitField0_ = (bitField0_ & ~0x00000040);
        someIntColumn_ = 0;
        bitField0_ = (bitField0_ & ~0x00000080);
        someLongColumn_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000100);
        if (fooBuilder_ == null) {
          foo_ = null;
        } else {
          fooBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000200);
        if (barBuilder_ == null) {
          bar_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000400);
        } else {
          barBuilder_.clear();
        }
        if (otherTimestampBuilder_ == null) {
          otherTimestamp_ = null;
        } else {
          otherTimestampBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000800);
        return this;
      }

      @Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.internal_static_prototest_ProtoTestEvent_descriptor;
      }

      @Override
      public org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent getDefaultInstanceForType() {
        return org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.getDefaultInstance();
      }

      @Override
      public org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent build() {
        org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @Override
      public org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent buildPartial() {
        org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent result = new org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.eventType_ = eventType_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.id_ = id_;
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          to_bitField0_ |= 0x00000004;
        }
        result.timestamp_ = timestamp_;
        if (((from_bitField0_ & 0x00000008) != 0)) {
          result.someOtherId_ = someOtherId_;
          to_bitField0_ |= 0x00000008;
        }
        if (((from_bitField0_ & 0x00000010) != 0)) {
          result.isValid_ = isValid_;
          to_bitField0_ |= 0x00000010;
        }
        if (((from_bitField0_ & 0x00000020) != 0)) {
          to_bitField0_ |= 0x00000020;
        }
        result.description_ = description_;
        if (((from_bitField0_ & 0x00000040) != 0)) {
          result.someFloatColumn_ = someFloatColumn_;
          to_bitField0_ |= 0x00000040;
        }
        if (((from_bitField0_ & 0x00000080) != 0)) {
          result.someIntColumn_ = someIntColumn_;
          to_bitField0_ |= 0x00000080;
        }
        if (((from_bitField0_ & 0x00000100) != 0)) {
          result.someLongColumn_ = someLongColumn_;
          to_bitField0_ |= 0x00000100;
        }
        if (((from_bitField0_ & 0x00000200) != 0)) {
          if (fooBuilder_ == null) {
            result.foo_ = foo_;
          } else {
            result.foo_ = fooBuilder_.build();
          }
          to_bitField0_ |= 0x00000200;
        }
        if (barBuilder_ == null) {
          if (((bitField0_ & 0x00000400) != 0)) {
            bar_ = java.util.Collections.unmodifiableList(bar_);
            bitField0_ = (bitField0_ & ~0x00000400);
          }
          result.bar_ = bar_;
        } else {
          result.bar_ = barBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000800) != 0)) {
          if (otherTimestampBuilder_ == null) {
            result.otherTimestamp_ = otherTimestamp_;
          } else {
            result.otherTimestamp_ = otherTimestampBuilder_.build();
          }
          to_bitField0_ |= 0x00000400;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

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

      public Builder mergeFrom(org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent other) {
        if (other == org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.getDefaultInstance()) return this;
        if (other.hasEventType()) {
          setEventType(other.getEventType());
        }
        if (other.hasId()) {
          setId(other.getId());
        }
        if (other.hasTimestamp()) {
          bitField0_ |= 0x00000004;
          timestamp_ = other.timestamp_;
          onChanged();
        }
        if (other.hasSomeOtherId()) {
          setSomeOtherId(other.getSomeOtherId());
        }
        if (other.hasIsValid()) {
          setIsValid(other.getIsValid());
        }
        if (other.hasDescription()) {
          bitField0_ |= 0x00000020;
          description_ = other.description_;
          onChanged();
        }
        if (other.hasSomeFloatColumn()) {
          setSomeFloatColumn(other.getSomeFloatColumn());
        }
        if (other.hasSomeIntColumn()) {
          setSomeIntColumn(other.getSomeIntColumn());
        }
        if (other.hasSomeLongColumn()) {
          setSomeLongColumn(other.getSomeLongColumn());
        }
        if (other.hasFoo()) {
          mergeFoo(other.getFoo());
        }
        if (barBuilder_ == null) {
          if (!other.bar_.isEmpty()) {
            if (bar_.isEmpty()) {
              bar_ = other.bar_;
              bitField0_ = (bitField0_ & ~0x00000400);
            } else {
              ensureBarIsMutable();
              bar_.addAll(other.bar_);
            }
            onChanged();
          }
        } else {
          if (!other.bar_.isEmpty()) {
            if (barBuilder_.isEmpty()) {
              barBuilder_.dispose();
              barBuilder_ = null;
              bar_ = other.bar_;
              bitField0_ = (bitField0_ & ~0x00000400);
              barBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getBarFieldBuilder() : null;
            } else {
              barBuilder_.addAllMessages(other.bar_);
            }
          }
        }
        if (other.hasOtherTimestamp()) {
          mergeOtherTimestamp(other.getOtherTimestamp());
        }
        this.mergeUnknownFields(other.unknownFields);
        onChanged();
        return this;
      }

      @Override
      public final boolean isInitialized() {
        if (!hasEventType()) {
          return false;
        }
        if (!hasId()) {
          return false;
        }
        if (!hasTimestamp()) {
          return false;
        }
        if (hasFoo()) {
          if (!getFoo().isInitialized()) {
            return false;
          }
        }
        for (int i = 0; i < getBarCount(); i++) {
          if (!getBar(i).isInitialized()) {
            return false;
          }
        }
        return true;
      }

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

      private int eventType_ = 0;
      /**
       * <code>required .prototest.ProtoTestEvent.EventCategory eventType = 1;</code>
       * @return Whether the eventType field is set.
       */
      @Override public boolean hasEventType() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>required .prototest.ProtoTestEvent.EventCategory eventType = 1;</code>
       * @return The eventType.
       */
      @Override
      public org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.EventCategory getEventType() {
        @SuppressWarnings("deprecation")
        org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.EventCategory result = org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.EventCategory.valueOf(eventType_);
        return result == null ? org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.EventCategory.CATEGORY_ZERO : result;
      }
      /**
       * <code>required .prototest.ProtoTestEvent.EventCategory eventType = 1;</code>
       * @param value The eventType to set.
       * @return This builder for chaining.
       */
      public Builder setEventType(org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.EventCategory value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000001;
        eventType_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>required .prototest.ProtoTestEvent.EventCategory eventType = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearEventType() {
        bitField0_ = (bitField0_ & ~0x00000001);
        eventType_ = 0;
        onChanged();
        return this;
      }

      private long id_ ;
      /**
       * <code>required uint64 id = 2;</code>
       * @return Whether the id field is set.
       */
      @Override
      public boolean hasId() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>required uint64 id = 2;</code>
       * @return The id.
       */
      @Override
      public long getId() {
        return id_;
      }
      /**
       * <code>required uint64 id = 2;</code>
       * @param value The id to set.
       * @return This builder for chaining.
       */
      public Builder setId(long value) {
        bitField0_ |= 0x00000002;
        id_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required uint64 id = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        id_ = 0L;
        onChanged();
        return this;
      }

      private java.lang.Object timestamp_ = "";
      /**
       * <code>required string timestamp = 3;</code>
       * @return Whether the timestamp field is set.
       */
      @Override
      public boolean hasTimestamp() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>required string timestamp = 3;</code>
       * @return The timestamp.
       */
      @Override
      public java.lang.String getTimestamp() {
        java.lang.Object ref = timestamp_;
        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()) {
            timestamp_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>required string timestamp = 3;</code>
       * @return The bytes for timestamp.
       */
      @Override
      public com.google.protobuf.ByteString
          getTimestampBytes() {
        java.lang.Object ref = timestamp_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          timestamp_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>required string timestamp = 3;</code>
       * @param value The timestamp to set.
       * @return This builder for chaining.
       */
      public Builder setTimestamp(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        timestamp_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required string timestamp = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearTimestamp() {
        bitField0_ = (bitField0_ & ~0x00000004);
        timestamp_ = getDefaultInstance().getTimestamp();
        onChanged();
        return this;
      }
      /**
       * <code>required string timestamp = 3;</code>
       * @param value The bytes for timestamp to set.
       * @return This builder for chaining.
       */
      public Builder setTimestampBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        timestamp_ = value;
        onChanged();
        return this;
      }

      private int someOtherId_ ;
      /**
       * <code>optional uint32 someOtherId = 4;</code>
       * @return Whether the someOtherId field is set.
       */
      @Override
      public boolean hasSomeOtherId() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <code>optional uint32 someOtherId = 4;</code>
       * @return The someOtherId.
       */
      @Override
      public int getSomeOtherId() {
        return someOtherId_;
      }
      /**
       * <code>optional uint32 someOtherId = 4;</code>
       * @param value The someOtherId to set.
       * @return This builder for chaining.
       */
      public Builder setSomeOtherId(int value) {
        bitField0_ |= 0x00000008;
        someOtherId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional uint32 someOtherId = 4;</code>
       * @return This builder for chaining.
       */
      public Builder clearSomeOtherId() {
        bitField0_ = (bitField0_ & ~0x00000008);
        someOtherId_ = 0;
        onChanged();
        return this;
      }

      private boolean isValid_ ;
      /**
       * <code>optional bool isValid = 5;</code>
       * @return Whether the isValid field is set.
       */
      @Override
      public boolean hasIsValid() {
        return ((bitField0_ & 0x00000010) != 0);
      }
      /**
       * <code>optional bool isValid = 5;</code>
       * @return The isValid.
       */
      @Override
      public boolean getIsValid() {
        return isValid_;
      }
      /**
       * <code>optional bool isValid = 5;</code>
       * @param value The isValid to set.
       * @return This builder for chaining.
       */
      public Builder setIsValid(boolean value) {
        bitField0_ |= 0x00000010;
        isValid_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool isValid = 5;</code>
       * @return This builder for chaining.
       */
      public Builder clearIsValid() {
        bitField0_ = (bitField0_ & ~0x00000010);
        isValid_ = false;
        onChanged();
        return this;
      }

      private java.lang.Object description_ = "";
      /**
       * <code>optional string description = 6;</code>
       * @return Whether the description field is set.
       */
      @Override
      public boolean hasDescription() {
        return ((bitField0_ & 0x00000020) != 0);
      }
      /**
       * <code>optional string description = 6;</code>
       * @return The description.
       */
      @Override
      public java.lang.String getDescription() {
        java.lang.Object ref = description_;
        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()) {
            description_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string description = 6;</code>
       * @return The bytes for description.
       */
      @Override
      public com.google.protobuf.ByteString
          getDescriptionBytes() {
        java.lang.Object ref = description_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          description_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string description = 6;</code>
       * @param value The description to set.
       * @return This builder for chaining.
       */
      public Builder setDescription(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000020;
        description_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string description = 6;</code>
       * @return This builder for chaining.
       */
      public Builder clearDescription() {
        bitField0_ = (bitField0_ & ~0x00000020);
        description_ = getDefaultInstance().getDescription();
        onChanged();
        return this;
      }
      /**
       * <code>optional string description = 6;</code>
       * @param value The bytes for description to set.
       * @return This builder for chaining.
       */
      public Builder setDescriptionBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000020;
        description_ = value;
        onChanged();
        return this;
      }

      private float someFloatColumn_ ;
      /**
       * <code>optional float someFloatColumn = 7;</code>
       * @return Whether the someFloatColumn field is set.
       */
      @Override
      public boolean hasSomeFloatColumn() {
        return ((bitField0_ & 0x00000040) != 0);
      }
      /**
       * <code>optional float someFloatColumn = 7;</code>
       * @return The someFloatColumn.
       */
      @Override
      public float getSomeFloatColumn() {
        return someFloatColumn_;
      }
      /**
       * <code>optional float someFloatColumn = 7;</code>
       * @param value The someFloatColumn to set.
       * @return This builder for chaining.
       */
      public Builder setSomeFloatColumn(float value) {
        bitField0_ |= 0x00000040;
        someFloatColumn_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional float someFloatColumn = 7;</code>
       * @return This builder for chaining.
       */
      public Builder clearSomeFloatColumn() {
        bitField0_ = (bitField0_ & ~0x00000040);
        someFloatColumn_ = 0F;
        onChanged();
        return this;
      }

      private int someIntColumn_ ;
      /**
       * <code>optional uint32 someIntColumn = 8;</code>
       * @return Whether the someIntColumn field is set.
       */
      @Override
      public boolean hasSomeIntColumn() {
        return ((bitField0_ & 0x00000080) != 0);
      }
      /**
       * <code>optional uint32 someIntColumn = 8;</code>
       * @return The someIntColumn.
       */
      @Override
      public int getSomeIntColumn() {
        return someIntColumn_;
      }
      /**
       * <code>optional uint32 someIntColumn = 8;</code>
       * @param value The someIntColumn to set.
       * @return This builder for chaining.
       */
      public Builder setSomeIntColumn(int value) {
        bitField0_ |= 0x00000080;
        someIntColumn_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional uint32 someIntColumn = 8;</code>
       * @return This builder for chaining.
       */
      public Builder clearSomeIntColumn() {
        bitField0_ = (bitField0_ & ~0x00000080);
        someIntColumn_ = 0;
        onChanged();
        return this;
      }

      private long someLongColumn_ ;
      /**
       * <code>optional uint64 someLongColumn = 9;</code>
       * @return Whether the someLongColumn field is set.
       */
      @Override
      public boolean hasSomeLongColumn() {
        return ((bitField0_ & 0x00000100) != 0);
      }
      /**
       * <code>optional uint64 someLongColumn = 9;</code>
       * @return The someLongColumn.
       */
      @Override
      public long getSomeLongColumn() {
        return someLongColumn_;
      }
      /**
       * <code>optional uint64 someLongColumn = 9;</code>
       * @param value The someLongColumn to set.
       * @return This builder for chaining.
       */
      public Builder setSomeLongColumn(long value) {
        bitField0_ |= 0x00000100;
        someLongColumn_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional uint64 someLongColumn = 9;</code>
       * @return This builder for chaining.
       */
      public Builder clearSomeLongColumn() {
        bitField0_ = (bitField0_ & ~0x00000100);
        someLongColumn_ = 0L;
        onChanged();
        return this;
      }

      private org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo foo_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo, org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.Builder, org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.FooOrBuilder> fooBuilder_;
      /**
       * <code>optional .prototest.ProtoTestEvent.Foo foo = 10;</code>
       * @return Whether the foo field is set.
       */
      @Override
      public boolean hasFoo() {
        return ((bitField0_ & 0x00000200) != 0);
      }
      /**
       * <code>optional .prototest.ProtoTestEvent.Foo foo = 10;</code>
       * @return The foo.
       */
      @Override
      public org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo getFoo() {
        if (fooBuilder_ == null) {
          return foo_ == null ? org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.getDefaultInstance() : foo_;
        } else {
          return fooBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .prototest.ProtoTestEvent.Foo foo = 10;</code>
       */
      public Builder setFoo(org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo value) {
        if (fooBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          foo_ = value;
          onChanged();
        } else {
          fooBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000200;
        return this;
      }
      /**
       * <code>optional .prototest.ProtoTestEvent.Foo foo = 10;</code>
       */
      public Builder setFoo(
          org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.Builder builderForValue) {
        if (fooBuilder_ == null) {
          foo_ = builderForValue.build();
          onChanged();
        } else {
          fooBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000200;
        return this;
      }
      /**
       * <code>optional .prototest.ProtoTestEvent.Foo foo = 10;</code>
       */
      public Builder mergeFoo(org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo value) {
        if (fooBuilder_ == null) {
          if (((bitField0_ & 0x00000200) != 0) &&
              foo_ != null &&
              foo_ != org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.getDefaultInstance()) {
            foo_ =
              org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.newBuilder(foo_).mergeFrom(value).buildPartial();
          } else {
            foo_ = value;
          }
          onChanged();
        } else {
          fooBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000200;
        return this;
      }
      /**
       * <code>optional .prototest.ProtoTestEvent.Foo foo = 10;</code>
       */
      public Builder clearFoo() {
        if (fooBuilder_ == null) {
          foo_ = null;
          onChanged();
        } else {
          fooBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000200);
        return this;
      }
      /**
       * <code>optional .prototest.ProtoTestEvent.Foo foo = 10;</code>
       */
      public org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.Builder getFooBuilder() {
        bitField0_ |= 0x00000200;
        onChanged();
        return getFooFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .prototest.ProtoTestEvent.Foo foo = 10;</code>
       */
      @Override
      public org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.FooOrBuilder getFooOrBuilder() {
        if (fooBuilder_ != null) {
          return fooBuilder_.getMessageOrBuilder();
        } else {
          return foo_ == null ?
              org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.getDefaultInstance() : foo_;
        }
      }
      /**
       * <code>optional .prototest.ProtoTestEvent.Foo foo = 10;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo, org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.Builder, org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.FooOrBuilder> 
          getFooFieldBuilder() {
        if (fooBuilder_ == null) {
          fooBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo, org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.Builder, org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.FooOrBuilder>(
                  getFoo(),
                  getParentForChildren(),
                  isClean());
          foo_ = null;
        }
        return fooBuilder_;
      }

      private java.util.List<org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo> bar_ =
        java.util.Collections.emptyList();
      private void ensureBarIsMutable() {
        if (!((bitField0_ & 0x00000400) != 0)) {
          bar_ = new java.util.ArrayList<org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo>(bar_);
          bitField0_ |= 0x00000400;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo, org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.Builder, org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.FooOrBuilder> barBuilder_;

      /**
       * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
       */
      @Override
      public java.util.List<org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo> getBarList() {
        if (barBuilder_ == null) {
          return java.util.Collections.unmodifiableList(bar_);
        } else {
          return barBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
       */
      @Override
      public int getBarCount() {
        if (barBuilder_ == null) {
          return bar_.size();
        } else {
          return barBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
       */
      @Override
      public org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo getBar(int index) {
        if (barBuilder_ == null) {
          return bar_.get(index);
        } else {
          return barBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
       */
      public Builder setBar(
          int index, org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo value) {
        if (barBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureBarIsMutable();
          bar_.set(index, value);
          onChanged();
        } else {
          barBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
       */
      public Builder setBar(
          int index, org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.Builder builderForValue) {
        if (barBuilder_ == null) {
          ensureBarIsMutable();
          bar_.set(index, builderForValue.build());
          onChanged();
        } else {
          barBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
       */
      public Builder addBar(org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo value) {
        if (barBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureBarIsMutable();
          bar_.add(value);
          onChanged();
        } else {
          barBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
       */
      public Builder addBar(
          int index, org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo value) {
        if (barBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureBarIsMutable();
          bar_.add(index, value);
          onChanged();
        } else {
          barBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
       */
      public Builder addBar(
          org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.Builder builderForValue) {
        if (barBuilder_ == null) {
          ensureBarIsMutable();
          bar_.add(builderForValue.build());
          onChanged();
        } else {
          barBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
       */
      public Builder addBar(
          int index, org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.Builder builderForValue) {
        if (barBuilder_ == null) {
          ensureBarIsMutable();
          bar_.add(index, builderForValue.build());
          onChanged();
        } else {
          barBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
       */
      public Builder addAllBar(
          java.lang.Iterable<? extends org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo> values) {
        if (barBuilder_ == null) {
          ensureBarIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, bar_);
          onChanged();
        } else {
          barBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
       */
      public Builder clearBar() {
        if (barBuilder_ == null) {
          bar_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000400);
          onChanged();
        } else {
          barBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
       */
      public Builder removeBar(int index) {
        if (barBuilder_ == null) {
          ensureBarIsMutable();
          bar_.remove(index);
          onChanged();
        } else {
          barBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
       */
      public org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.Builder getBarBuilder(
          int index) {
        return getBarFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
       */
      @Override
      public org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.FooOrBuilder getBarOrBuilder(
          int index) {
        if (barBuilder_ == null) {
          return bar_.get(index);  } else {
          return barBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
       */
      @Override
      public java.util.List<? extends org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.FooOrBuilder>
           getBarOrBuilderList() {
        if (barBuilder_ != null) {
          return barBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(bar_);
        }
      }
      /**
       * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
       */
      public org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.Builder addBarBuilder() {
        return getBarFieldBuilder().addBuilder(
            org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.getDefaultInstance());
      }
      /**
       * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
       */
      public org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.Builder addBarBuilder(
          int index) {
        return getBarFieldBuilder().addBuilder(
            index, org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.getDefaultInstance());
      }
      /**
       * <code>repeated .prototest.ProtoTestEvent.Foo bar = 11;</code>
       */
      public java.util.List<org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.Builder> 
           getBarBuilderList() {
        return getBarFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo, org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.Builder, org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.FooOrBuilder> 
          getBarFieldBuilder() {
        if (barBuilder_ == null) {
          barBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo, org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.Foo.Builder, org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent.FooOrBuilder>(
                  bar_,
                  ((bitField0_ & 0x00000400) != 0),
                  getParentForChildren(),
                  isClean());
          bar_ = null;
        }
        return barBuilder_;
      }

      private com.google.protobuf.Timestamp otherTimestamp_;
      private com.google.protobuf.SingleFieldBuilderV3<
          com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> otherTimestampBuilder_;
      /**
       * <code>optional .google.protobuf.Timestamp otherTimestamp = 12;</code>
       * @return Whether the otherTimestamp field is set.
       */
      @Override
      public boolean hasOtherTimestamp() {
        return ((bitField0_ & 0x00000800) != 0);
      }
      /**
       * <code>optional .google.protobuf.Timestamp otherTimestamp = 12;</code>
       * @return The otherTimestamp.
       */
      @Override
      public com.google.protobuf.Timestamp getOtherTimestamp() {
        if (otherTimestampBuilder_ == null) {
          return otherTimestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : otherTimestamp_;
        } else {
          return otherTimestampBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .google.protobuf.Timestamp otherTimestamp = 12;</code>
       */
      public Builder setOtherTimestamp(com.google.protobuf.Timestamp value) {
        if (otherTimestampBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          otherTimestamp_ = value;
          onChanged();
        } else {
          otherTimestampBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000800;
        return this;
      }
      /**
       * <code>optional .google.protobuf.Timestamp otherTimestamp = 12;</code>
       */
      public Builder setOtherTimestamp(
          com.google.protobuf.Timestamp.Builder builderForValue) {
        if (otherTimestampBuilder_ == null) {
          otherTimestamp_ = builderForValue.build();
          onChanged();
        } else {
          otherTimestampBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000800;
        return this;
      }
      /**
       * <code>optional .google.protobuf.Timestamp otherTimestamp = 12;</code>
       */
      public Builder mergeOtherTimestamp(com.google.protobuf.Timestamp value) {
        if (otherTimestampBuilder_ == null) {
          if (((bitField0_ & 0x00000800) != 0) &&
              otherTimestamp_ != null &&
              otherTimestamp_ != com.google.protobuf.Timestamp.getDefaultInstance()) {
            otherTimestamp_ =
              com.google.protobuf.Timestamp.newBuilder(otherTimestamp_).mergeFrom(value).buildPartial();
          } else {
            otherTimestamp_ = value;
          }
          onChanged();
        } else {
          otherTimestampBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000800;
        return this;
      }
      /**
       * <code>optional .google.protobuf.Timestamp otherTimestamp = 12;</code>
       */
      public Builder clearOtherTimestamp() {
        if (otherTimestampBuilder_ == null) {
          otherTimestamp_ = null;
          onChanged();
        } else {
          otherTimestampBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000800);
        return this;
      }
      /**
       * <code>optional .google.protobuf.Timestamp otherTimestamp = 12;</code>
       */
      public com.google.protobuf.Timestamp.Builder getOtherTimestampBuilder() {
        bitField0_ |= 0x00000800;
        onChanged();
        return getOtherTimestampFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .google.protobuf.Timestamp otherTimestamp = 12;</code>
       */
      @Override
      public com.google.protobuf.TimestampOrBuilder getOtherTimestampOrBuilder() {
        if (otherTimestampBuilder_ != null) {
          return otherTimestampBuilder_.getMessageOrBuilder();
        } else {
          return otherTimestamp_ == null ?
              com.google.protobuf.Timestamp.getDefaultInstance() : otherTimestamp_;
        }
      }
      /**
       * <code>optional .google.protobuf.Timestamp otherTimestamp = 12;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> 
          getOtherTimestampFieldBuilder() {
        if (otherTimestampBuilder_ == null) {
          otherTimestampBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder>(
                  getOtherTimestamp(),
                  getParentForChildren(),
                  isClean());
          otherTimestamp_ = null;
        }
        return otherTimestampBuilder_;
      }
      @Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

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


      // @@protoc_insertion_point(builder_scope:prototest.ProtoTestEvent)
    }

    // @@protoc_insertion_point(class_scope:prototest.ProtoTestEvent)
    private static final org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent();
    }

    public static org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<ProtoTestEvent>
        PARSER = new com.google.protobuf.AbstractParser<ProtoTestEvent>() {
      @Override
      public ProtoTestEvent parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new ProtoTestEvent(input, extensionRegistry);
      }
    };

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

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

    @Override
    public org.apache.druid.data.input.protobuf.ProtoTestEventWrapper.ProtoTestEvent getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_prototest_ProtoTestEvent_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_prototest_ProtoTestEvent_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_prototest_ProtoTestEvent_Foo_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_prototest_ProtoTestEvent_Foo_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\017Prototest.proto\022\tprototest\032\037google/pro" +
      "tobuf/timestamp.proto\"\326\003\n\016ProtoTestEvent" +
      "\022:\n\teventType\030\001 \002(\0162\'.prototest.ProtoTes" +
      "tEvent.EventCategory\022\n\n\002id\030\002 \002(\004\022\021\n\ttime" +
      "stamp\030\003 \002(\t\022\023\n\013someOtherId\030\004 \001(\r\022\017\n\007isVa" +
      "lid\030\005 \001(\010\022\023\n\013description\030\006 \001(\t\022\027\n\017someFl" +
      "oatColumn\030\007 \001(\002\022\025\n\rsomeIntColumn\030\010 \001(\r\022\026" +
      "\n\016someLongColumn\030\t \001(\004\022*\n\003foo\030\n \001(\0132\035.pr" +
      "ototest.ProtoTestEvent.Foo\022*\n\003bar\030\013 \003(\0132" +
      "\035.prototest.ProtoTestEvent.Foo\0222\n\016otherT" +
      "imestamp\030\014 \001(\0132\032.google.protobuf.Timesta" +
      "mp\032\022\n\003Foo\022\013\n\003bar\030\001 \002(\t\"F\n\rEventCategory\022" +
      "\021\n\rCATEGORY_ZERO\020\000\022\020\n\014CATEGORY_ONE\020\001\022\020\n\014" +
      "CATEGORY_TWO\020\002B=\n$org.apache.druid.data." +
      "input.protobufB\025ProtoTestEventWrapper"
    };
    descriptor = com.google.protobuf.Descriptors.FileDescriptor
      .internalBuildGeneratedFileFrom(descriptorData,
        new com.google.protobuf.Descriptors.FileDescriptor[] {
          com.google.protobuf.TimestampProto.getDescriptor(),
        });
    internal_static_prototest_ProtoTestEvent_descriptor =
      getDescriptor().getMessageTypes().get(0);
    internal_static_prototest_ProtoTestEvent_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_prototest_ProtoTestEvent_descriptor,
        new java.lang.String[] { "EventType", "Id", "Timestamp", "SomeOtherId", "IsValid", "Description", "SomeFloatColumn", "SomeIntColumn", "SomeLongColumn", "Foo", "Bar", "OtherTimestamp", });
    internal_static_prototest_ProtoTestEvent_Foo_descriptor =
      internal_static_prototest_ProtoTestEvent_descriptor.getNestedTypes().get(0);
    internal_static_prototest_ProtoTestEvent_Foo_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_prototest_ProtoTestEvent_Foo_descriptor,
        new java.lang.String[] { "Bar", });
    com.google.protobuf.TimestampProto.getDescriptor();
  }

  // @@protoc_insertion_point(outer_class_scope)
}
