// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: src/test/protobuf/test_multiple_files.proto

// Protobuf Java Version: 4.26.1
package org.apache.avro.protobuf.multiplefiles;

/**
 * Protobuf type {@code org.apache.avro.protobuf.multiplefiles.Foo}
 */
public final class Foo extends com.google.protobuf.GeneratedMessage implements
    // @@protoc_insertion_point(message_implements:org.apache.avro.protobuf.multiplefiles.Foo)
    FooOrBuilder {
  private static final long serialVersionUID = 0L;
  static {
    com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(
        com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, /* minor= */ 26, /* patch= */ 1,
        /* suffix= */ "", Foo.class.getName());
  }

  // Use Foo.newBuilder() to construct.
  private Foo(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
    super(builder);
  }

  private Foo() {
    string_ = "";
    bytes_ = com.google.protobuf.ByteString.EMPTY;
    enum_ = 3;
    intArray_ = emptyIntList();
    fooArray_ = java.util.Collections.emptyList();
    syms_ = java.util.Collections.emptyList();
  }

  public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() {
    return org.apache.avro.protobuf.multiplefiles.TestMultipleFiles.internal_static_org_apache_avro_protobuf_multiplefiles_Foo_descriptor;
  }

  @java.lang.Override
  protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() {
    return org.apache.avro.protobuf.multiplefiles.TestMultipleFiles.internal_static_org_apache_avro_protobuf_multiplefiles_Foo_fieldAccessorTable
        .ensureFieldAccessorsInitialized(org.apache.avro.protobuf.multiplefiles.Foo.class,
            org.apache.avro.protobuf.multiplefiles.Foo.Builder.class);
  }

  private int bitField0_;
  public static final int INT32_FIELD_NUMBER = 1;
  private int int32_ = 0;

  /**
   * <pre>
   * all the primitive types
   * </pre>
   *
   * <code>required int32 int32 = 1;</code>
   * 
   * @return Whether the int32 field is set.
   */
  @java.lang.Override
  public boolean hasInt32() {
    return ((bitField0_ & 0x00000001) != 0);
  }

  /**
   * <pre>
   * all the primitive types
   * </pre>
   *
   * <code>required int32 int32 = 1;</code>
   * 
   * @return The int32.
   */
  @java.lang.Override
  public int getInt32() {
    return int32_;
  }

  public static final int INT64_FIELD_NUMBER = 2;
  private long int64_ = 0L;

  /**
   * <code>optional int64 int64 = 2;</code>
   * 
   * @return Whether the int64 field is set.
   */
  @java.lang.Override
  public boolean hasInt64() {
    return ((bitField0_ & 0x00000002) != 0);
  }

  /**
   * <code>optional int64 int64 = 2;</code>
   * 
   * @return The int64.
   */
  @java.lang.Override
  public long getInt64() {
    return int64_;
  }

  public static final int UINT32_FIELD_NUMBER = 3;
  private int uint32_ = 0;

  /**
   * <code>optional uint32 uint32 = 3;</code>
   * 
   * @return Whether the uint32 field is set.
   */
  @java.lang.Override
  public boolean hasUint32() {
    return ((bitField0_ & 0x00000004) != 0);
  }

  /**
   * <code>optional uint32 uint32 = 3;</code>
   * 
   * @return The uint32.
   */
  @java.lang.Override
  public int getUint32() {
    return uint32_;
  }

  public static final int UINT64_FIELD_NUMBER = 4;
  private long uint64_ = 0L;

  /**
   * <code>optional uint64 uint64 = 4;</code>
   * 
   * @return Whether the uint64 field is set.
   */
  @java.lang.Override
  public boolean hasUint64() {
    return ((bitField0_ & 0x00000008) != 0);
  }

  /**
   * <code>optional uint64 uint64 = 4;</code>
   * 
   * @return The uint64.
   */
  @java.lang.Override
  public long getUint64() {
    return uint64_;
  }

  public static final int SINT32_FIELD_NUMBER = 5;
  private int sint32_ = 0;

  /**
   * <code>optional sint32 sint32 = 5;</code>
   * 
   * @return Whether the sint32 field is set.
   */
  @java.lang.Override
  public boolean hasSint32() {
    return ((bitField0_ & 0x00000010) != 0);
  }

  /**
   * <code>optional sint32 sint32 = 5;</code>
   * 
   * @return The sint32.
   */
  @java.lang.Override
  public int getSint32() {
    return sint32_;
  }

  public static final int SINT64_FIELD_NUMBER = 6;
  private long sint64_ = 0L;

  /**
   * <code>optional sint64 sint64 = 6;</code>
   * 
   * @return Whether the sint64 field is set.
   */
  @java.lang.Override
  public boolean hasSint64() {
    return ((bitField0_ & 0x00000020) != 0);
  }

  /**
   * <code>optional sint64 sint64 = 6;</code>
   * 
   * @return The sint64.
   */
  @java.lang.Override
  public long getSint64() {
    return sint64_;
  }

  public static final int FIXED32_FIELD_NUMBER = 7;
  private int fixed32_ = 0;

  /**
   * <code>optional fixed32 fixed32 = 7;</code>
   * 
   * @return Whether the fixed32 field is set.
   */
  @java.lang.Override
  public boolean hasFixed32() {
    return ((bitField0_ & 0x00000040) != 0);
  }

  /**
   * <code>optional fixed32 fixed32 = 7;</code>
   * 
   * @return The fixed32.
   */
  @java.lang.Override
  public int getFixed32() {
    return fixed32_;
  }

  public static final int FIXED64_FIELD_NUMBER = 8;
  private long fixed64_ = 0L;

  /**
   * <code>optional fixed64 fixed64 = 8;</code>
   * 
   * @return Whether the fixed64 field is set.
   */
  @java.lang.Override
  public boolean hasFixed64() {
    return ((bitField0_ & 0x00000080) != 0);
  }

  /**
   * <code>optional fixed64 fixed64 = 8;</code>
   * 
   * @return The fixed64.
   */
  @java.lang.Override
  public long getFixed64() {
    return fixed64_;
  }

  public static final int SFIXED32_FIELD_NUMBER = 9;
  private int sfixed32_ = 0;

  /**
   * <code>optional sfixed32 sfixed32 = 9;</code>
   * 
   * @return Whether the sfixed32 field is set.
   */
  @java.lang.Override
  public boolean hasSfixed32() {
    return ((bitField0_ & 0x00000100) != 0);
  }

  /**
   * <code>optional sfixed32 sfixed32 = 9;</code>
   * 
   * @return The sfixed32.
   */
  @java.lang.Override
  public int getSfixed32() {
    return sfixed32_;
  }

  public static final int SFIXED64_FIELD_NUMBER = 10;
  private long sfixed64_ = 0L;

  /**
   * <code>optional sfixed64 sfixed64 = 10;</code>
   * 
   * @return Whether the sfixed64 field is set.
   */
  @java.lang.Override
  public boolean hasSfixed64() {
    return ((bitField0_ & 0x00000200) != 0);
  }

  /**
   * <code>optional sfixed64 sfixed64 = 10;</code>
   * 
   * @return The sfixed64.
   */
  @java.lang.Override
  public long getSfixed64() {
    return sfixed64_;
  }

  public static final int FLOAT_FIELD_NUMBER = 11;
  private float float_ = 0F;

  /**
   * <code>optional float float = 11;</code>
   * 
   * @return Whether the float field is set.
   */
  @java.lang.Override
  public boolean hasFloat() {
    return ((bitField0_ & 0x00000400) != 0);
  }

  /**
   * <code>optional float float = 11;</code>
   * 
   * @return The float.
   */
  @java.lang.Override
  public float getFloat() {
    return float_;
  }

  public static final int DOUBLE_FIELD_NUMBER = 12;
  private double double_ = 0D;

  /**
   * <code>optional double double = 12;</code>
   * 
   * @return Whether the double field is set.
   */
  @java.lang.Override
  public boolean hasDouble() {
    return ((bitField0_ & 0x00000800) != 0);
  }

  /**
   * <code>optional double double = 12;</code>
   * 
   * @return The double.
   */
  @java.lang.Override
  public double getDouble() {
    return double_;
  }

  public static final int BOOL_FIELD_NUMBER = 13;
  private boolean bool_ = false;

  /**
   * <code>optional bool bool = 13;</code>
   * 
   * @return Whether the bool field is set.
   */
  @java.lang.Override
  public boolean hasBool() {
    return ((bitField0_ & 0x00001000) != 0);
  }

  /**
   * <code>optional bool bool = 13;</code>
   * 
   * @return The bool.
   */
  @java.lang.Override
  public boolean getBool() {
    return bool_;
  }

  public static final int STRING_FIELD_NUMBER = 14;
  @SuppressWarnings("serial")
  private volatile java.lang.Object string_ = "";

  /**
   * <code>optional string string = 14;</code>
   * 
   * @return Whether the string field is set.
   */
  @java.lang.Override
  public boolean hasString() {
    return ((bitField0_ & 0x00002000) != 0);
  }

  /**
   * <code>optional string string = 14;</code>
   * 
   * @return The string.
   */
  @java.lang.Override
  public java.lang.String getString() {
    java.lang.Object ref = string_;
    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()) {
        string_ = s;
      }
      return s;
    }
  }

  /**
   * <code>optional string string = 14;</code>
   * 
   * @return The bytes for string.
   */
  @java.lang.Override
  public com.google.protobuf.ByteString getStringBytes() {
    java.lang.Object ref = string_;
    if (ref instanceof java.lang.String) {
      com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8((java.lang.String) ref);
      string_ = b;
      return b;
    } else {
      return (com.google.protobuf.ByteString) ref;
    }
  }

  public static final int BYTES_FIELD_NUMBER = 15;
  private com.google.protobuf.ByteString bytes_ = com.google.protobuf.ByteString.EMPTY;

  /**
   * <code>optional bytes bytes = 15;</code>
   * 
   * @return Whether the bytes field is set.
   */
  @java.lang.Override
  public boolean hasBytes() {
    return ((bitField0_ & 0x00004000) != 0);
  }

  /**
   * <code>optional bytes bytes = 15;</code>
   * 
   * @return The bytes.
   */
  @java.lang.Override
  public com.google.protobuf.ByteString getBytes() {
    return bytes_;
  }

  public static final int ENUM_FIELD_NUMBER = 16;
  private int enum_ = 3;

  /**
   * <code>optional .org.apache.avro.protobuf.multiplefiles.A enum = 16 [default = Z];</code>
   * 
   * @return Whether the enum field is set.
   */
  @java.lang.Override
  public boolean hasEnum() {
    return ((bitField0_ & 0x00008000) != 0);
  }

  /**
   * <code>optional .org.apache.avro.protobuf.multiplefiles.A enum = 16 [default = Z];</code>
   * 
   * @return The enum.
   */
  @java.lang.Override
  public org.apache.avro.protobuf.multiplefiles.A getEnum() {
    org.apache.avro.protobuf.multiplefiles.A result = org.apache.avro.protobuf.multiplefiles.A.forNumber(enum_);
    return result == null ? org.apache.avro.protobuf.multiplefiles.A.Z : result;
  }

  public static final int INTARRAY_FIELD_NUMBER = 17;
  @SuppressWarnings("serial")
  private com.google.protobuf.Internal.IntList intArray_ = emptyIntList();

  /**
   * <pre>
   * some repeated types
   * </pre>
   *
   * <code>repeated int32 intArray = 17;</code>
   * 
   * @return A list containing the intArray.
   */
  @java.lang.Override
  public java.util.List<java.lang.Integer> getIntArrayList() {
    return intArray_;
  }

  /**
   * <pre>
   * some repeated types
   * </pre>
   *
   * <code>repeated int32 intArray = 17;</code>
   * 
   * @return The count of intArray.
   */
  public int getIntArrayCount() {
    return intArray_.size();
  }

  /**
   * <pre>
   * some repeated types
   * </pre>
   *
   * <code>repeated int32 intArray = 17;</code>
   * 
   * @param index The index of the element to return.
   * @return The intArray at the given index.
   */
  public int getIntArray(int index) {
    return intArray_.getInt(index);
  }

  public static final int FOOARRAY_FIELD_NUMBER = 20;
  @SuppressWarnings("serial")
  private java.util.List<org.apache.avro.protobuf.multiplefiles.Foo> fooArray_;

  /**
   * <code>repeated .org.apache.avro.protobuf.multiplefiles.Foo fooArray = 20;</code>
   */
  @java.lang.Override
  public java.util.List<org.apache.avro.protobuf.multiplefiles.Foo> getFooArrayList() {
    return fooArray_;
  }

  /**
   * <code>repeated .org.apache.avro.protobuf.multiplefiles.Foo fooArray = 20;</code>
   */
  @java.lang.Override
  public java.util.List<? extends org.apache.avro.protobuf.multiplefiles.FooOrBuilder> getFooArrayOrBuilderList() {
    return fooArray_;
  }

  /**
   * <code>repeated .org.apache.avro.protobuf.multiplefiles.Foo fooArray = 20;</code>
   */
  @java.lang.Override
  public int getFooArrayCount() {
    return fooArray_.size();
  }

  /**
   * <code>repeated .org.apache.avro.protobuf.multiplefiles.Foo fooArray = 20;</code>
   */
  @java.lang.Override
  public org.apache.avro.protobuf.multiplefiles.Foo getFooArray(int index) {
    return fooArray_.get(index);
  }

  /**
   * <code>repeated .org.apache.avro.protobuf.multiplefiles.Foo fooArray = 20;</code>
   */
  @java.lang.Override
  public org.apache.avro.protobuf.multiplefiles.FooOrBuilder getFooArrayOrBuilder(int index) {
    return fooArray_.get(index);
  }

  public static final int SYMS_FIELD_NUMBER = 19;
  @SuppressWarnings("serial")
  private java.util.List<java.lang.Integer> syms_;
  private static final com.google.protobuf.Internal.ListAdapter.Converter<java.lang.Integer, org.apache.avro.protobuf.multiplefiles.A> syms_converter_ = new com.google.protobuf.Internal.ListAdapter.Converter<java.lang.Integer, org.apache.avro.protobuf.multiplefiles.A>() {
    public org.apache.avro.protobuf.multiplefiles.A convert(java.lang.Integer from) {
      org.apache.avro.protobuf.multiplefiles.A result = org.apache.avro.protobuf.multiplefiles.A.forNumber(from);
      return result == null ? org.apache.avro.protobuf.multiplefiles.A.X : result;
    }
  };

  /**
   * <code>repeated .org.apache.avro.protobuf.multiplefiles.A syms = 19;</code>
   * 
   * @return A list containing the syms.
   */
  @java.lang.Override
  public java.util.List<org.apache.avro.protobuf.multiplefiles.A> getSymsList() {
    return new com.google.protobuf.Internal.ListAdapter<java.lang.Integer, org.apache.avro.protobuf.multiplefiles.A>(
        syms_, syms_converter_);
  }

  /**
   * <code>repeated .org.apache.avro.protobuf.multiplefiles.A syms = 19;</code>
   * 
   * @return The count of syms.
   */
  @java.lang.Override
  public int getSymsCount() {
    return syms_.size();
  }

  /**
   * <code>repeated .org.apache.avro.protobuf.multiplefiles.A syms = 19;</code>
   * 
   * @param index The index of the element to return.
   * @return The syms at the given index.
   */
  @java.lang.Override
  public org.apache.avro.protobuf.multiplefiles.A getSyms(int index) {
    return syms_converter_.convert(syms_.get(index));
  }

  public static final int FOO_FIELD_NUMBER = 18;
  private org.apache.avro.protobuf.multiplefiles.Foo foo_;

  /**
   * <pre>
   * a recursive type
   * </pre>
   *
   * <code>optional .org.apache.avro.protobuf.multiplefiles.Foo foo = 18;</code>
   * 
   * @return Whether the foo field is set.
   */
  @java.lang.Override
  public boolean hasFoo() {
    return ((bitField0_ & 0x00010000) != 0);
  }

  /**
   * <pre>
   * a recursive type
   * </pre>
   *
   * <code>optional .org.apache.avro.protobuf.multiplefiles.Foo foo = 18;</code>
   * 
   * @return The foo.
   */
  @java.lang.Override
  public org.apache.avro.protobuf.multiplefiles.Foo getFoo() {
    return foo_ == null ? org.apache.avro.protobuf.multiplefiles.Foo.getDefaultInstance() : foo_;
  }

  /**
   * <pre>
   * a recursive type
   * </pre>
   *
   * <code>optional .org.apache.avro.protobuf.multiplefiles.Foo foo = 18;</code>
   */
  @java.lang.Override
  public org.apache.avro.protobuf.multiplefiles.FooOrBuilder getFooOrBuilder() {
    return foo_ == null ? org.apache.avro.protobuf.multiplefiles.Foo.getDefaultInstance() : foo_;
  }

  public static final int TIMESTAMP_FIELD_NUMBER = 21;
  private com.google.protobuf.Timestamp timestamp_;

  /**
   * <pre>
   * a predefined message type
   * </pre>
   *
   * <code>optional .google.protobuf.Timestamp timestamp = 21;</code>
   * 
   * @return Whether the timestamp field is set.
   */
  @java.lang.Override
  public boolean hasTimestamp() {
    return ((bitField0_ & 0x00020000) != 0);
  }

  /**
   * <pre>
   * a predefined message type
   * </pre>
   *
   * <code>optional .google.protobuf.Timestamp timestamp = 21;</code>
   * 
   * @return The timestamp.
   */
  @java.lang.Override
  public com.google.protobuf.Timestamp getTimestamp() {
    return timestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : timestamp_;
  }

  /**
   * <pre>
   * a predefined message type
   * </pre>
   *
   * <code>optional .google.protobuf.Timestamp timestamp = 21;</code>
   */
  @java.lang.Override
  public com.google.protobuf.TimestampOrBuilder getTimestampOrBuilder() {
    return timestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : timestamp_;
  }

  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 (!hasInt32()) {
      memoizedIsInitialized = 0;
      return false;
    }
    for (int i = 0; i < getFooArrayCount(); i++) {
      if (!getFooArray(i).isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
    }
    if (hasFoo()) {
      if (!getFoo().isInitialized()) {
        memoizedIsInitialized = 0;
        return false;
      }
    }
    memoizedIsInitialized = 1;
    return true;
  }

  @java.lang.Override
  public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
    if (((bitField0_ & 0x00000001) != 0)) {
      output.writeInt32(1, int32_);
    }
    if (((bitField0_ & 0x00000002) != 0)) {
      output.writeInt64(2, int64_);
    }
    if (((bitField0_ & 0x00000004) != 0)) {
      output.writeUInt32(3, uint32_);
    }
    if (((bitField0_ & 0x00000008) != 0)) {
      output.writeUInt64(4, uint64_);
    }
    if (((bitField0_ & 0x00000010) != 0)) {
      output.writeSInt32(5, sint32_);
    }
    if (((bitField0_ & 0x00000020) != 0)) {
      output.writeSInt64(6, sint64_);
    }
    if (((bitField0_ & 0x00000040) != 0)) {
      output.writeFixed32(7, fixed32_);
    }
    if (((bitField0_ & 0x00000080) != 0)) {
      output.writeFixed64(8, fixed64_);
    }
    if (((bitField0_ & 0x00000100) != 0)) {
      output.writeSFixed32(9, sfixed32_);
    }
    if (((bitField0_ & 0x00000200) != 0)) {
      output.writeSFixed64(10, sfixed64_);
    }
    if (((bitField0_ & 0x00000400) != 0)) {
      output.writeFloat(11, float_);
    }
    if (((bitField0_ & 0x00000800) != 0)) {
      output.writeDouble(12, double_);
    }
    if (((bitField0_ & 0x00001000) != 0)) {
      output.writeBool(13, bool_);
    }
    if (((bitField0_ & 0x00002000) != 0)) {
      com.google.protobuf.GeneratedMessage.writeString(output, 14, string_);
    }
    if (((bitField0_ & 0x00004000) != 0)) {
      output.writeBytes(15, bytes_);
    }
    if (((bitField0_ & 0x00008000) != 0)) {
      output.writeEnum(16, enum_);
    }
    for (int i = 0; i < intArray_.size(); i++) {
      output.writeInt32(17, intArray_.getInt(i));
    }
    if (((bitField0_ & 0x00010000) != 0)) {
      output.writeMessage(18, getFoo());
    }
    for (int i = 0; i < syms_.size(); i++) {
      output.writeEnum(19, syms_.get(i));
    }
    for (int i = 0; i < fooArray_.size(); i++) {
      output.writeMessage(20, fooArray_.get(i));
    }
    if (((bitField0_ & 0x00020000) != 0)) {
      output.writeMessage(21, getTimestamp());
    }
    getUnknownFields().writeTo(output);
  }

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

    size = 0;
    if (((bitField0_ & 0x00000001) != 0)) {
      size += com.google.protobuf.CodedOutputStream.computeInt32Size(1, int32_);
    }
    if (((bitField0_ & 0x00000002) != 0)) {
      size += com.google.protobuf.CodedOutputStream.computeInt64Size(2, int64_);
    }
    if (((bitField0_ & 0x00000004) != 0)) {
      size += com.google.protobuf.CodedOutputStream.computeUInt32Size(3, uint32_);
    }
    if (((bitField0_ & 0x00000008) != 0)) {
      size += com.google.protobuf.CodedOutputStream.computeUInt64Size(4, uint64_);
    }
    if (((bitField0_ & 0x00000010) != 0)) {
      size += com.google.protobuf.CodedOutputStream.computeSInt32Size(5, sint32_);
    }
    if (((bitField0_ & 0x00000020) != 0)) {
      size += com.google.protobuf.CodedOutputStream.computeSInt64Size(6, sint64_);
    }
    if (((bitField0_ & 0x00000040) != 0)) {
      size += com.google.protobuf.CodedOutputStream.computeFixed32Size(7, fixed32_);
    }
    if (((bitField0_ & 0x00000080) != 0)) {
      size += com.google.protobuf.CodedOutputStream.computeFixed64Size(8, fixed64_);
    }
    if (((bitField0_ & 0x00000100) != 0)) {
      size += com.google.protobuf.CodedOutputStream.computeSFixed32Size(9, sfixed32_);
    }
    if (((bitField0_ & 0x00000200) != 0)) {
      size += com.google.protobuf.CodedOutputStream.computeSFixed64Size(10, sfixed64_);
    }
    if (((bitField0_ & 0x00000400) != 0)) {
      size += com.google.protobuf.CodedOutputStream.computeFloatSize(11, float_);
    }
    if (((bitField0_ & 0x00000800) != 0)) {
      size += com.google.protobuf.CodedOutputStream.computeDoubleSize(12, double_);
    }
    if (((bitField0_ & 0x00001000) != 0)) {
      size += com.google.protobuf.CodedOutputStream.computeBoolSize(13, bool_);
    }
    if (((bitField0_ & 0x00002000) != 0)) {
      size += com.google.protobuf.GeneratedMessage.computeStringSize(14, string_);
    }
    if (((bitField0_ & 0x00004000) != 0)) {
      size += com.google.protobuf.CodedOutputStream.computeBytesSize(15, bytes_);
    }
    if (((bitField0_ & 0x00008000) != 0)) {
      size += com.google.protobuf.CodedOutputStream.computeEnumSize(16, enum_);
    }
    {
      int dataSize = 0;
      for (int i = 0; i < intArray_.size(); i++) {
        dataSize += com.google.protobuf.CodedOutputStream.computeInt32SizeNoTag(intArray_.getInt(i));
      }
      size += dataSize;
      size += 2 * getIntArrayList().size();
    }
    if (((bitField0_ & 0x00010000) != 0)) {
      size += com.google.protobuf.CodedOutputStream.computeMessageSize(18, getFoo());
    }
    {
      int dataSize = 0;
      for (int i = 0; i < syms_.size(); i++) {
        dataSize += com.google.protobuf.CodedOutputStream.computeEnumSizeNoTag(syms_.get(i));
      }
      size += dataSize;
      size += 2 * syms_.size();
    }
    for (int i = 0; i < fooArray_.size(); i++) {
      size += com.google.protobuf.CodedOutputStream.computeMessageSize(20, fooArray_.get(i));
    }
    if (((bitField0_ & 0x00020000) != 0)) {
      size += com.google.protobuf.CodedOutputStream.computeMessageSize(21, getTimestamp());
    }
    size += getUnknownFields().getSerializedSize();
    memoizedSize = size;
    return size;
  }

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

    if (hasInt32() != other.hasInt32())
      return false;
    if (hasInt32()) {
      if (getInt32() != other.getInt32())
        return false;
    }
    if (hasInt64() != other.hasInt64())
      return false;
    if (hasInt64()) {
      if (getInt64() != other.getInt64())
        return false;
    }
    if (hasUint32() != other.hasUint32())
      return false;
    if (hasUint32()) {
      if (getUint32() != other.getUint32())
        return false;
    }
    if (hasUint64() != other.hasUint64())
      return false;
    if (hasUint64()) {
      if (getUint64() != other.getUint64())
        return false;
    }
    if (hasSint32() != other.hasSint32())
      return false;
    if (hasSint32()) {
      if (getSint32() != other.getSint32())
        return false;
    }
    if (hasSint64() != other.hasSint64())
      return false;
    if (hasSint64()) {
      if (getSint64() != other.getSint64())
        return false;
    }
    if (hasFixed32() != other.hasFixed32())
      return false;
    if (hasFixed32()) {
      if (getFixed32() != other.getFixed32())
        return false;
    }
    if (hasFixed64() != other.hasFixed64())
      return false;
    if (hasFixed64()) {
      if (getFixed64() != other.getFixed64())
        return false;
    }
    if (hasSfixed32() != other.hasSfixed32())
      return false;
    if (hasSfixed32()) {
      if (getSfixed32() != other.getSfixed32())
        return false;
    }
    if (hasSfixed64() != other.hasSfixed64())
      return false;
    if (hasSfixed64()) {
      if (getSfixed64() != other.getSfixed64())
        return false;
    }
    if (hasFloat() != other.hasFloat())
      return false;
    if (hasFloat()) {
      if (java.lang.Float.floatToIntBits(getFloat()) != java.lang.Float.floatToIntBits(other.getFloat()))
        return false;
    }
    if (hasDouble() != other.hasDouble())
      return false;
    if (hasDouble()) {
      if (java.lang.Double.doubleToLongBits(getDouble()) != java.lang.Double.doubleToLongBits(other.getDouble()))
        return false;
    }
    if (hasBool() != other.hasBool())
      return false;
    if (hasBool()) {
      if (getBool() != other.getBool())
        return false;
    }
    if (hasString() != other.hasString())
      return false;
    if (hasString()) {
      if (!getString().equals(other.getString()))
        return false;
    }
    if (hasBytes() != other.hasBytes())
      return false;
    if (hasBytes()) {
      if (!getBytes().equals(other.getBytes()))
        return false;
    }
    if (hasEnum() != other.hasEnum())
      return false;
    if (hasEnum()) {
      if (enum_ != other.enum_)
        return false;
    }
    if (!getIntArrayList().equals(other.getIntArrayList()))
      return false;
    if (!getFooArrayList().equals(other.getFooArrayList()))
      return false;
    if (!syms_.equals(other.syms_))
      return false;
    if (hasFoo() != other.hasFoo())
      return false;
    if (hasFoo()) {
      if (!getFoo().equals(other.getFoo()))
        return false;
    }
    if (hasTimestamp() != other.hasTimestamp())
      return false;
    if (hasTimestamp()) {
      if (!getTimestamp().equals(other.getTimestamp()))
        return false;
    }
    if (!getUnknownFields().equals(other.getUnknownFields()))
      return false;
    return true;
  }

  @java.lang.Override
  public int hashCode() {
    if (memoizedHashCode != 0) {
      return memoizedHashCode;
    }
    int hash = 41;
    hash = (19 * hash) + getDescriptor().hashCode();
    if (hasInt32()) {
      hash = (37 * hash) + INT32_FIELD_NUMBER;
      hash = (53 * hash) + getInt32();
    }
    if (hasInt64()) {
      hash = (37 * hash) + INT64_FIELD_NUMBER;
      hash = (53 * hash) + com.google.protobuf.Internal.hashLong(getInt64());
    }
    if (hasUint32()) {
      hash = (37 * hash) + UINT32_FIELD_NUMBER;
      hash = (53 * hash) + getUint32();
    }
    if (hasUint64()) {
      hash = (37 * hash) + UINT64_FIELD_NUMBER;
      hash = (53 * hash) + com.google.protobuf.Internal.hashLong(getUint64());
    }
    if (hasSint32()) {
      hash = (37 * hash) + SINT32_FIELD_NUMBER;
      hash = (53 * hash) + getSint32();
    }
    if (hasSint64()) {
      hash = (37 * hash) + SINT64_FIELD_NUMBER;
      hash = (53 * hash) + com.google.protobuf.Internal.hashLong(getSint64());
    }
    if (hasFixed32()) {
      hash = (37 * hash) + FIXED32_FIELD_NUMBER;
      hash = (53 * hash) + getFixed32();
    }
    if (hasFixed64()) {
      hash = (37 * hash) + FIXED64_FIELD_NUMBER;
      hash = (53 * hash) + com.google.protobuf.Internal.hashLong(getFixed64());
    }
    if (hasSfixed32()) {
      hash = (37 * hash) + SFIXED32_FIELD_NUMBER;
      hash = (53 * hash) + getSfixed32();
    }
    if (hasSfixed64()) {
      hash = (37 * hash) + SFIXED64_FIELD_NUMBER;
      hash = (53 * hash) + com.google.protobuf.Internal.hashLong(getSfixed64());
    }
    if (hasFloat()) {
      hash = (37 * hash) + FLOAT_FIELD_NUMBER;
      hash = (53 * hash) + java.lang.Float.floatToIntBits(getFloat());
    }
    if (hasDouble()) {
      hash = (37 * hash) + DOUBLE_FIELD_NUMBER;
      hash = (53 * hash) + com.google.protobuf.Internal.hashLong(java.lang.Double.doubleToLongBits(getDouble()));
    }
    if (hasBool()) {
      hash = (37 * hash) + BOOL_FIELD_NUMBER;
      hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(getBool());
    }
    if (hasString()) {
      hash = (37 * hash) + STRING_FIELD_NUMBER;
      hash = (53 * hash) + getString().hashCode();
    }
    if (hasBytes()) {
      hash = (37 * hash) + BYTES_FIELD_NUMBER;
      hash = (53 * hash) + getBytes().hashCode();
    }
    if (hasEnum()) {
      hash = (37 * hash) + ENUM_FIELD_NUMBER;
      hash = (53 * hash) + enum_;
    }
    if (getIntArrayCount() > 0) {
      hash = (37 * hash) + INTARRAY_FIELD_NUMBER;
      hash = (53 * hash) + getIntArrayList().hashCode();
    }
    if (getFooArrayCount() > 0) {
      hash = (37 * hash) + FOOARRAY_FIELD_NUMBER;
      hash = (53 * hash) + getFooArrayList().hashCode();
    }
    if (getSymsCount() > 0) {
      hash = (37 * hash) + SYMS_FIELD_NUMBER;
      hash = (53 * hash) + syms_.hashCode();
    }
    if (hasFoo()) {
      hash = (37 * hash) + FOO_FIELD_NUMBER;
      hash = (53 * hash) + getFoo().hashCode();
    }
    if (hasTimestamp()) {
      hash = (37 * hash) + TIMESTAMP_FIELD_NUMBER;
      hash = (53 * hash) + getTimestamp().hashCode();
    }
    hash = (29 * hash) + getUnknownFields().hashCode();
    memoizedHashCode = hash;
    return hash;
  }

  public static org.apache.avro.protobuf.multiplefiles.Foo parseFrom(java.nio.ByteBuffer data)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data);
  }

  public static org.apache.avro.protobuf.multiplefiles.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.avro.protobuf.multiplefiles.Foo parseFrom(com.google.protobuf.ByteString data)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data);
  }

  public static org.apache.avro.protobuf.multiplefiles.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.avro.protobuf.multiplefiles.Foo parseFrom(byte[] data)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data);
  }

  public static org.apache.avro.protobuf.multiplefiles.Foo parseFrom(byte[] data,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data, extensionRegistry);
  }

  public static org.apache.avro.protobuf.multiplefiles.Foo parseFrom(java.io.InputStream input)
      throws java.io.IOException {
    return com.google.protobuf.GeneratedMessage.parseWithIOException(PARSER, input);
  }

  public static org.apache.avro.protobuf.multiplefiles.Foo parseFrom(java.io.InputStream input,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException {
    return com.google.protobuf.GeneratedMessage.parseWithIOException(PARSER, input, extensionRegistry);
  }

  public static org.apache.avro.protobuf.multiplefiles.Foo parseDelimitedFrom(java.io.InputStream input)
      throws java.io.IOException {
    return com.google.protobuf.GeneratedMessage.parseDelimitedWithIOException(PARSER, input);
  }

  public static org.apache.avro.protobuf.multiplefiles.Foo parseDelimitedFrom(java.io.InputStream input,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException {
    return com.google.protobuf.GeneratedMessage.parseDelimitedWithIOException(PARSER, input, extensionRegistry);
  }

  public static org.apache.avro.protobuf.multiplefiles.Foo parseFrom(com.google.protobuf.CodedInputStream input)
      throws java.io.IOException {
    return com.google.protobuf.GeneratedMessage.parseWithIOException(PARSER, input);
  }

  public static org.apache.avro.protobuf.multiplefiles.Foo parseFrom(com.google.protobuf.CodedInputStream input,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException {
    return com.google.protobuf.GeneratedMessage.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.avro.protobuf.multiplefiles.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.GeneratedMessage.BuilderParent parent) {
    Builder builder = new Builder(parent);
    return builder;
  }

  /**
   * Protobuf type {@code org.apache.avro.protobuf.multiplefiles.Foo}
   */
  public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder<Builder> implements
      // @@protoc_insertion_point(builder_implements:org.apache.avro.protobuf.multiplefiles.Foo)
      org.apache.avro.protobuf.multiplefiles.FooOrBuilder {
    public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() {
      return org.apache.avro.protobuf.multiplefiles.TestMultipleFiles.internal_static_org_apache_avro_protobuf_multiplefiles_Foo_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() {
      return org.apache.avro.protobuf.multiplefiles.TestMultipleFiles.internal_static_org_apache_avro_protobuf_multiplefiles_Foo_fieldAccessorTable
          .ensureFieldAccessorsInitialized(org.apache.avro.protobuf.multiplefiles.Foo.class,
              org.apache.avro.protobuf.multiplefiles.Foo.Builder.class);
    }

    // Construct using org.apache.avro.protobuf.multiplefiles.Foo.newBuilder()
    private Builder() {
      maybeForceBuilderInitialization();
    }

    private Builder(com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      super(parent);
      maybeForceBuilderInitialization();
    }

    private void maybeForceBuilderInitialization() {
      if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        getFooArrayFieldBuilder();
        getFooFieldBuilder();
        getTimestampFieldBuilder();
      }
    }

    @java.lang.Override
    public Builder clear() {
      super.clear();
      bitField0_ = 0;
      int32_ = 0;
      int64_ = 0L;
      uint32_ = 0;
      uint64_ = 0L;
      sint32_ = 0;
      sint64_ = 0L;
      fixed32_ = 0;
      fixed64_ = 0L;
      sfixed32_ = 0;
      sfixed64_ = 0L;
      float_ = 0F;
      double_ = 0D;
      bool_ = false;
      string_ = "";
      bytes_ = com.google.protobuf.ByteString.EMPTY;
      enum_ = 3;
      intArray_ = emptyIntList();
      if (fooArrayBuilder_ == null) {
        fooArray_ = java.util.Collections.emptyList();
      } else {
        fooArray_ = null;
        fooArrayBuilder_.clear();
      }
      bitField0_ = (bitField0_ & ~0x00020000);
      syms_ = java.util.Collections.emptyList();
      bitField0_ = (bitField0_ & ~0x00040000);
      foo_ = null;
      if (fooBuilder_ != null) {
        fooBuilder_.dispose();
        fooBuilder_ = null;
      }
      timestamp_ = null;
      if (timestampBuilder_ != null) {
        timestampBuilder_.dispose();
        timestampBuilder_ = null;
      }
      return this;
    }

    @java.lang.Override
    public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() {
      return org.apache.avro.protobuf.multiplefiles.TestMultipleFiles.internal_static_org_apache_avro_protobuf_multiplefiles_Foo_descriptor;
    }

    @java.lang.Override
    public org.apache.avro.protobuf.multiplefiles.Foo getDefaultInstanceForType() {
      return org.apache.avro.protobuf.multiplefiles.Foo.getDefaultInstance();
    }

    @java.lang.Override
    public org.apache.avro.protobuf.multiplefiles.Foo build() {
      org.apache.avro.protobuf.multiplefiles.Foo result = buildPartial();
      if (!result.isInitialized()) {
        throw newUninitializedMessageException(result);
      }
      return result;
    }

    @java.lang.Override
    public org.apache.avro.protobuf.multiplefiles.Foo buildPartial() {
      org.apache.avro.protobuf.multiplefiles.Foo result = new org.apache.avro.protobuf.multiplefiles.Foo(this);
      buildPartialRepeatedFields(result);
      if (bitField0_ != 0) {
        buildPartial0(result);
      }
      onBuilt();
      return result;
    }

    private void buildPartialRepeatedFields(org.apache.avro.protobuf.multiplefiles.Foo result) {
      if (fooArrayBuilder_ == null) {
        if (((bitField0_ & 0x00020000) != 0)) {
          fooArray_ = java.util.Collections.unmodifiableList(fooArray_);
          bitField0_ = (bitField0_ & ~0x00020000);
        }
        result.fooArray_ = fooArray_;
      } else {
        result.fooArray_ = fooArrayBuilder_.build();
      }
      if (((bitField0_ & 0x00040000) != 0)) {
        syms_ = java.util.Collections.unmodifiableList(syms_);
        bitField0_ = (bitField0_ & ~0x00040000);
      }
      result.syms_ = syms_;
    }

    private void buildPartial0(org.apache.avro.protobuf.multiplefiles.Foo result) {
      int from_bitField0_ = bitField0_;
      int to_bitField0_ = 0;
      if (((from_bitField0_ & 0x00000001) != 0)) {
        result.int32_ = int32_;
        to_bitField0_ |= 0x00000001;
      }
      if (((from_bitField0_ & 0x00000002) != 0)) {
        result.int64_ = int64_;
        to_bitField0_ |= 0x00000002;
      }
      if (((from_bitField0_ & 0x00000004) != 0)) {
        result.uint32_ = uint32_;
        to_bitField0_ |= 0x00000004;
      }
      if (((from_bitField0_ & 0x00000008) != 0)) {
        result.uint64_ = uint64_;
        to_bitField0_ |= 0x00000008;
      }
      if (((from_bitField0_ & 0x00000010) != 0)) {
        result.sint32_ = sint32_;
        to_bitField0_ |= 0x00000010;
      }
      if (((from_bitField0_ & 0x00000020) != 0)) {
        result.sint64_ = sint64_;
        to_bitField0_ |= 0x00000020;
      }
      if (((from_bitField0_ & 0x00000040) != 0)) {
        result.fixed32_ = fixed32_;
        to_bitField0_ |= 0x00000040;
      }
      if (((from_bitField0_ & 0x00000080) != 0)) {
        result.fixed64_ = fixed64_;
        to_bitField0_ |= 0x00000080;
      }
      if (((from_bitField0_ & 0x00000100) != 0)) {
        result.sfixed32_ = sfixed32_;
        to_bitField0_ |= 0x00000100;
      }
      if (((from_bitField0_ & 0x00000200) != 0)) {
        result.sfixed64_ = sfixed64_;
        to_bitField0_ |= 0x00000200;
      }
      if (((from_bitField0_ & 0x00000400) != 0)) {
        result.float_ = float_;
        to_bitField0_ |= 0x00000400;
      }
      if (((from_bitField0_ & 0x00000800) != 0)) {
        result.double_ = double_;
        to_bitField0_ |= 0x00000800;
      }
      if (((from_bitField0_ & 0x00001000) != 0)) {
        result.bool_ = bool_;
        to_bitField0_ |= 0x00001000;
      }
      if (((from_bitField0_ & 0x00002000) != 0)) {
        result.string_ = string_;
        to_bitField0_ |= 0x00002000;
      }
      if (((from_bitField0_ & 0x00004000) != 0)) {
        result.bytes_ = bytes_;
        to_bitField0_ |= 0x00004000;
      }
      if (((from_bitField0_ & 0x00008000) != 0)) {
        result.enum_ = enum_;
        to_bitField0_ |= 0x00008000;
      }
      if (((from_bitField0_ & 0x00010000) != 0)) {
        intArray_.makeImmutable();
        result.intArray_ = intArray_;
      }
      if (((from_bitField0_ & 0x00080000) != 0)) {
        result.foo_ = fooBuilder_ == null ? foo_ : fooBuilder_.build();
        to_bitField0_ |= 0x00010000;
      }
      if (((from_bitField0_ & 0x00100000) != 0)) {
        result.timestamp_ = timestampBuilder_ == null ? timestamp_ : timestampBuilder_.build();
        to_bitField0_ |= 0x00020000;
      }
      result.bitField0_ |= to_bitField0_;
    }

    @java.lang.Override
    public Builder mergeFrom(com.google.protobuf.Message other) {
      if (other instanceof org.apache.avro.protobuf.multiplefiles.Foo) {
        return mergeFrom((org.apache.avro.protobuf.multiplefiles.Foo) other);
      } else {
        super.mergeFrom(other);
        return this;
      }
    }

    public Builder mergeFrom(org.apache.avro.protobuf.multiplefiles.Foo other) {
      if (other == org.apache.avro.protobuf.multiplefiles.Foo.getDefaultInstance())
        return this;
      if (other.hasInt32()) {
        setInt32(other.getInt32());
      }
      if (other.hasInt64()) {
        setInt64(other.getInt64());
      }
      if (other.hasUint32()) {
        setUint32(other.getUint32());
      }
      if (other.hasUint64()) {
        setUint64(other.getUint64());
      }
      if (other.hasSint32()) {
        setSint32(other.getSint32());
      }
      if (other.hasSint64()) {
        setSint64(other.getSint64());
      }
      if (other.hasFixed32()) {
        setFixed32(other.getFixed32());
      }
      if (other.hasFixed64()) {
        setFixed64(other.getFixed64());
      }
      if (other.hasSfixed32()) {
        setSfixed32(other.getSfixed32());
      }
      if (other.hasSfixed64()) {
        setSfixed64(other.getSfixed64());
      }
      if (other.hasFloat()) {
        setFloat(other.getFloat());
      }
      if (other.hasDouble()) {
        setDouble(other.getDouble());
      }
      if (other.hasBool()) {
        setBool(other.getBool());
      }
      if (other.hasString()) {
        string_ = other.string_;
        bitField0_ |= 0x00002000;
        onChanged();
      }
      if (other.hasBytes()) {
        setBytes(other.getBytes());
      }
      if (other.hasEnum()) {
        setEnum(other.getEnum());
      }
      if (!other.intArray_.isEmpty()) {
        if (intArray_.isEmpty()) {
          intArray_ = other.intArray_;
          intArray_.makeImmutable();
          bitField0_ |= 0x00010000;
        } else {
          ensureIntArrayIsMutable();
          intArray_.addAll(other.intArray_);
        }
        onChanged();
      }
      if (fooArrayBuilder_ == null) {
        if (!other.fooArray_.isEmpty()) {
          if (fooArray_.isEmpty()) {
            fooArray_ = other.fooArray_;
            bitField0_ = (bitField0_ & ~0x00020000);
          } else {
            ensureFooArrayIsMutable();
            fooArray_.addAll(other.fooArray_);
          }
          onChanged();
        }
      } else {
        if (!other.fooArray_.isEmpty()) {
          if (fooArrayBuilder_.isEmpty()) {
            fooArrayBuilder_.dispose();
            fooArrayBuilder_ = null;
            fooArray_ = other.fooArray_;
            bitField0_ = (bitField0_ & ~0x00020000);
            fooArrayBuilder_ = com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? getFooArrayFieldBuilder()
                : null;
          } else {
            fooArrayBuilder_.addAllMessages(other.fooArray_);
          }
        }
      }
      if (!other.syms_.isEmpty()) {
        if (syms_.isEmpty()) {
          syms_ = other.syms_;
          bitField0_ = (bitField0_ & ~0x00040000);
        } else {
          ensureSymsIsMutable();
          syms_.addAll(other.syms_);
        }
        onChanged();
      }
      if (other.hasFoo()) {
        mergeFoo(other.getFoo());
      }
      if (other.hasTimestamp()) {
        mergeTimestamp(other.getTimestamp());
      }
      this.mergeUnknownFields(other.getUnknownFields());
      onChanged();
      return this;
    }

    @java.lang.Override
    public final boolean isInitialized() {
      if (!hasInt32()) {
        return false;
      }
      for (int i = 0; i < getFooArrayCount(); i++) {
        if (!getFooArray(i).isInitialized()) {
          return false;
        }
      }
      if (hasFoo()) {
        if (!getFoo().isInitialized()) {
          return false;
        }
      }
      return true;
    }

    @java.lang.Override
    public Builder mergeFrom(com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException {
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
          case 0:
            done = true;
            break;
          case 8: {
            int32_ = input.readInt32();
            bitField0_ |= 0x00000001;
            break;
          } // case 8
          case 16: {
            int64_ = input.readInt64();
            bitField0_ |= 0x00000002;
            break;
          } // case 16
          case 24: {
            uint32_ = input.readUInt32();
            bitField0_ |= 0x00000004;
            break;
          } // case 24
          case 32: {
            uint64_ = input.readUInt64();
            bitField0_ |= 0x00000008;
            break;
          } // case 32
          case 40: {
            sint32_ = input.readSInt32();
            bitField0_ |= 0x00000010;
            break;
          } // case 40
          case 48: {
            sint64_ = input.readSInt64();
            bitField0_ |= 0x00000020;
            break;
          } // case 48
          case 61: {
            fixed32_ = input.readFixed32();
            bitField0_ |= 0x00000040;
            break;
          } // case 61
          case 65: {
            fixed64_ = input.readFixed64();
            bitField0_ |= 0x00000080;
            break;
          } // case 65
          case 77: {
            sfixed32_ = input.readSFixed32();
            bitField0_ |= 0x00000100;
            break;
          } // case 77
          case 81: {
            sfixed64_ = input.readSFixed64();
            bitField0_ |= 0x00000200;
            break;
          } // case 81
          case 93: {
            float_ = input.readFloat();
            bitField0_ |= 0x00000400;
            break;
          } // case 93
          case 97: {
            double_ = input.readDouble();
            bitField0_ |= 0x00000800;
            break;
          } // case 97
          case 104: {
            bool_ = input.readBool();
            bitField0_ |= 0x00001000;
            break;
          } // case 104
          case 114: {
            string_ = input.readBytes();
            bitField0_ |= 0x00002000;
            break;
          } // case 114
          case 122: {
            bytes_ = input.readBytes();
            bitField0_ |= 0x00004000;
            break;
          } // case 122
          case 128: {
            int tmpRaw = input.readEnum();
            org.apache.avro.protobuf.multiplefiles.A tmpValue = org.apache.avro.protobuf.multiplefiles.A
                .forNumber(tmpRaw);
            if (tmpValue == null) {
              mergeUnknownVarintField(16, tmpRaw);
            } else {
              enum_ = tmpRaw;
              bitField0_ |= 0x00008000;
            }
            break;
          } // case 128
          case 136: {
            int v = input.readInt32();
            ensureIntArrayIsMutable();
            intArray_.addInt(v);
            break;
          } // case 136
          case 138: {
            int length = input.readRawVarint32();
            int limit = input.pushLimit(length);
            ensureIntArrayIsMutable();
            while (input.getBytesUntilLimit() > 0) {
              intArray_.addInt(input.readInt32());
            }
            input.popLimit(limit);
            break;
          } // case 138
          case 146: {
            input.readMessage(getFooFieldBuilder().getBuilder(), extensionRegistry);
            bitField0_ |= 0x00080000;
            break;
          } // case 146
          case 152: {
            int tmpRaw = input.readEnum();
            org.apache.avro.protobuf.multiplefiles.A tmpValue = org.apache.avro.protobuf.multiplefiles.A
                .forNumber(tmpRaw);
            if (tmpValue == null) {
              mergeUnknownVarintField(19, tmpRaw);
            } else {
              ensureSymsIsMutable();
              syms_.add(tmpRaw);
            }
            break;
          } // case 152
          case 154: {
            int length = input.readRawVarint32();
            int oldLimit = input.pushLimit(length);
            while (input.getBytesUntilLimit() > 0) {
              int tmpRaw = input.readEnum();
              org.apache.avro.protobuf.multiplefiles.A tmpValue = org.apache.avro.protobuf.multiplefiles.A
                  .forNumber(tmpRaw);
              if (tmpValue == null) {
                mergeUnknownVarintField(19, tmpRaw);
              } else {
                ensureSymsIsMutable();
                syms_.add(tmpRaw);
              }
            }
            input.popLimit(oldLimit);
            break;
          } // case 154
          case 162: {
            org.apache.avro.protobuf.multiplefiles.Foo m = input
                .readMessage(org.apache.avro.protobuf.multiplefiles.Foo.parser(), extensionRegistry);
            if (fooArrayBuilder_ == null) {
              ensureFooArrayIsMutable();
              fooArray_.add(m);
            } else {
              fooArrayBuilder_.addMessage(m);
            }
            break;
          } // case 162
          case 170: {
            input.readMessage(getTimestampFieldBuilder().getBuilder(), extensionRegistry);
            bitField0_ |= 0x00100000;
            break;
          } // case 170
          default: {
            if (!super.parseUnknownField(input, extensionRegistry, tag)) {
              done = true; // was an endgroup tag
            }
            break;
          } // default:
          } // switch (tag)
        } // while (!done)
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.unwrapIOException();
      } finally {
        onChanged();
      } // finally
      return this;
    }

    private int bitField0_;

    private int int32_;

    /**
     * <pre>
     * all the primitive types
     * </pre>
     *
     * <code>required int32 int32 = 1;</code>
     * 
     * @return Whether the int32 field is set.
     */
    @java.lang.Override
    public boolean hasInt32() {
      return ((bitField0_ & 0x00000001) != 0);
    }

    /**
     * <pre>
     * all the primitive types
     * </pre>
     *
     * <code>required int32 int32 = 1;</code>
     * 
     * @return The int32.
     */
    @java.lang.Override
    public int getInt32() {
      return int32_;
    }

    /**
     * <pre>
     * all the primitive types
     * </pre>
     *
     * <code>required int32 int32 = 1;</code>
     * 
     * @param value The int32 to set.
     * @return This builder for chaining.
     */
    public Builder setInt32(int value) {

      int32_ = value;
      bitField0_ |= 0x00000001;
      onChanged();
      return this;
    }

    /**
     * <pre>
     * all the primitive types
     * </pre>
     *
     * <code>required int32 int32 = 1;</code>
     * 
     * @return This builder for chaining.
     */
    public Builder clearInt32() {
      bitField0_ = (bitField0_ & ~0x00000001);
      int32_ = 0;
      onChanged();
      return this;
    }

    private long int64_;

    /**
     * <code>optional int64 int64 = 2;</code>
     * 
     * @return Whether the int64 field is set.
     */
    @java.lang.Override
    public boolean hasInt64() {
      return ((bitField0_ & 0x00000002) != 0);
    }

    /**
     * <code>optional int64 int64 = 2;</code>
     * 
     * @return The int64.
     */
    @java.lang.Override
    public long getInt64() {
      return int64_;
    }

    /**
     * <code>optional int64 int64 = 2;</code>
     * 
     * @param value The int64 to set.
     * @return This builder for chaining.
     */
    public Builder setInt64(long value) {

      int64_ = value;
      bitField0_ |= 0x00000002;
      onChanged();
      return this;
    }

    /**
     * <code>optional int64 int64 = 2;</code>
     * 
     * @return This builder for chaining.
     */
    public Builder clearInt64() {
      bitField0_ = (bitField0_ & ~0x00000002);
      int64_ = 0L;
      onChanged();
      return this;
    }

    private int uint32_;

    /**
     * <code>optional uint32 uint32 = 3;</code>
     * 
     * @return Whether the uint32 field is set.
     */
    @java.lang.Override
    public boolean hasUint32() {
      return ((bitField0_ & 0x00000004) != 0);
    }

    /**
     * <code>optional uint32 uint32 = 3;</code>
     * 
     * @return The uint32.
     */
    @java.lang.Override
    public int getUint32() {
      return uint32_;
    }

    /**
     * <code>optional uint32 uint32 = 3;</code>
     * 
     * @param value The uint32 to set.
     * @return This builder for chaining.
     */
    public Builder setUint32(int value) {

      uint32_ = value;
      bitField0_ |= 0x00000004;
      onChanged();
      return this;
    }

    /**
     * <code>optional uint32 uint32 = 3;</code>
     * 
     * @return This builder for chaining.
     */
    public Builder clearUint32() {
      bitField0_ = (bitField0_ & ~0x00000004);
      uint32_ = 0;
      onChanged();
      return this;
    }

    private long uint64_;

    /**
     * <code>optional uint64 uint64 = 4;</code>
     * 
     * @return Whether the uint64 field is set.
     */
    @java.lang.Override
    public boolean hasUint64() {
      return ((bitField0_ & 0x00000008) != 0);
    }

    /**
     * <code>optional uint64 uint64 = 4;</code>
     * 
     * @return The uint64.
     */
    @java.lang.Override
    public long getUint64() {
      return uint64_;
    }

    /**
     * <code>optional uint64 uint64 = 4;</code>
     * 
     * @param value The uint64 to set.
     * @return This builder for chaining.
     */
    public Builder setUint64(long value) {

      uint64_ = value;
      bitField0_ |= 0x00000008;
      onChanged();
      return this;
    }

    /**
     * <code>optional uint64 uint64 = 4;</code>
     * 
     * @return This builder for chaining.
     */
    public Builder clearUint64() {
      bitField0_ = (bitField0_ & ~0x00000008);
      uint64_ = 0L;
      onChanged();
      return this;
    }

    private int sint32_;

    /**
     * <code>optional sint32 sint32 = 5;</code>
     * 
     * @return Whether the sint32 field is set.
     */
    @java.lang.Override
    public boolean hasSint32() {
      return ((bitField0_ & 0x00000010) != 0);
    }

    /**
     * <code>optional sint32 sint32 = 5;</code>
     * 
     * @return The sint32.
     */
    @java.lang.Override
    public int getSint32() {
      return sint32_;
    }

    /**
     * <code>optional sint32 sint32 = 5;</code>
     * 
     * @param value The sint32 to set.
     * @return This builder for chaining.
     */
    public Builder setSint32(int value) {

      sint32_ = value;
      bitField0_ |= 0x00000010;
      onChanged();
      return this;
    }

    /**
     * <code>optional sint32 sint32 = 5;</code>
     * 
     * @return This builder for chaining.
     */
    public Builder clearSint32() {
      bitField0_ = (bitField0_ & ~0x00000010);
      sint32_ = 0;
      onChanged();
      return this;
    }

    private long sint64_;

    /**
     * <code>optional sint64 sint64 = 6;</code>
     * 
     * @return Whether the sint64 field is set.
     */
    @java.lang.Override
    public boolean hasSint64() {
      return ((bitField0_ & 0x00000020) != 0);
    }

    /**
     * <code>optional sint64 sint64 = 6;</code>
     * 
     * @return The sint64.
     */
    @java.lang.Override
    public long getSint64() {
      return sint64_;
    }

    /**
     * <code>optional sint64 sint64 = 6;</code>
     * 
     * @param value The sint64 to set.
     * @return This builder for chaining.
     */
    public Builder setSint64(long value) {

      sint64_ = value;
      bitField0_ |= 0x00000020;
      onChanged();
      return this;
    }

    /**
     * <code>optional sint64 sint64 = 6;</code>
     * 
     * @return This builder for chaining.
     */
    public Builder clearSint64() {
      bitField0_ = (bitField0_ & ~0x00000020);
      sint64_ = 0L;
      onChanged();
      return this;
    }

    private int fixed32_;

    /**
     * <code>optional fixed32 fixed32 = 7;</code>
     * 
     * @return Whether the fixed32 field is set.
     */
    @java.lang.Override
    public boolean hasFixed32() {
      return ((bitField0_ & 0x00000040) != 0);
    }

    /**
     * <code>optional fixed32 fixed32 = 7;</code>
     * 
     * @return The fixed32.
     */
    @java.lang.Override
    public int getFixed32() {
      return fixed32_;
    }

    /**
     * <code>optional fixed32 fixed32 = 7;</code>
     * 
     * @param value The fixed32 to set.
     * @return This builder for chaining.
     */
    public Builder setFixed32(int value) {

      fixed32_ = value;
      bitField0_ |= 0x00000040;
      onChanged();
      return this;
    }

    /**
     * <code>optional fixed32 fixed32 = 7;</code>
     * 
     * @return This builder for chaining.
     */
    public Builder clearFixed32() {
      bitField0_ = (bitField0_ & ~0x00000040);
      fixed32_ = 0;
      onChanged();
      return this;
    }

    private long fixed64_;

    /**
     * <code>optional fixed64 fixed64 = 8;</code>
     * 
     * @return Whether the fixed64 field is set.
     */
    @java.lang.Override
    public boolean hasFixed64() {
      return ((bitField0_ & 0x00000080) != 0);
    }

    /**
     * <code>optional fixed64 fixed64 = 8;</code>
     * 
     * @return The fixed64.
     */
    @java.lang.Override
    public long getFixed64() {
      return fixed64_;
    }

    /**
     * <code>optional fixed64 fixed64 = 8;</code>
     * 
     * @param value The fixed64 to set.
     * @return This builder for chaining.
     */
    public Builder setFixed64(long value) {

      fixed64_ = value;
      bitField0_ |= 0x00000080;
      onChanged();
      return this;
    }

    /**
     * <code>optional fixed64 fixed64 = 8;</code>
     * 
     * @return This builder for chaining.
     */
    public Builder clearFixed64() {
      bitField0_ = (bitField0_ & ~0x00000080);
      fixed64_ = 0L;
      onChanged();
      return this;
    }

    private int sfixed32_;

    /**
     * <code>optional sfixed32 sfixed32 = 9;</code>
     * 
     * @return Whether the sfixed32 field is set.
     */
    @java.lang.Override
    public boolean hasSfixed32() {
      return ((bitField0_ & 0x00000100) != 0);
    }

    /**
     * <code>optional sfixed32 sfixed32 = 9;</code>
     * 
     * @return The sfixed32.
     */
    @java.lang.Override
    public int getSfixed32() {
      return sfixed32_;
    }

    /**
     * <code>optional sfixed32 sfixed32 = 9;</code>
     * 
     * @param value The sfixed32 to set.
     * @return This builder for chaining.
     */
    public Builder setSfixed32(int value) {

      sfixed32_ = value;
      bitField0_ |= 0x00000100;
      onChanged();
      return this;
    }

    /**
     * <code>optional sfixed32 sfixed32 = 9;</code>
     * 
     * @return This builder for chaining.
     */
    public Builder clearSfixed32() {
      bitField0_ = (bitField0_ & ~0x00000100);
      sfixed32_ = 0;
      onChanged();
      return this;
    }

    private long sfixed64_;

    /**
     * <code>optional sfixed64 sfixed64 = 10;</code>
     * 
     * @return Whether the sfixed64 field is set.
     */
    @java.lang.Override
    public boolean hasSfixed64() {
      return ((bitField0_ & 0x00000200) != 0);
    }

    /**
     * <code>optional sfixed64 sfixed64 = 10;</code>
     * 
     * @return The sfixed64.
     */
    @java.lang.Override
    public long getSfixed64() {
      return sfixed64_;
    }

    /**
     * <code>optional sfixed64 sfixed64 = 10;</code>
     * 
     * @param value The sfixed64 to set.
     * @return This builder for chaining.
     */
    public Builder setSfixed64(long value) {

      sfixed64_ = value;
      bitField0_ |= 0x00000200;
      onChanged();
      return this;
    }

    /**
     * <code>optional sfixed64 sfixed64 = 10;</code>
     * 
     * @return This builder for chaining.
     */
    public Builder clearSfixed64() {
      bitField0_ = (bitField0_ & ~0x00000200);
      sfixed64_ = 0L;
      onChanged();
      return this;
    }

    private float float_;

    /**
     * <code>optional float float = 11;</code>
     * 
     * @return Whether the float field is set.
     */
    @java.lang.Override
    public boolean hasFloat() {
      return ((bitField0_ & 0x00000400) != 0);
    }

    /**
     * <code>optional float float = 11;</code>
     * 
     * @return The float.
     */
    @java.lang.Override
    public float getFloat() {
      return float_;
    }

    /**
     * <code>optional float float = 11;</code>
     * 
     * @param value The float to set.
     * @return This builder for chaining.
     */
    public Builder setFloat(float value) {

      float_ = value;
      bitField0_ |= 0x00000400;
      onChanged();
      return this;
    }

    /**
     * <code>optional float float = 11;</code>
     * 
     * @return This builder for chaining.
     */
    public Builder clearFloat() {
      bitField0_ = (bitField0_ & ~0x00000400);
      float_ = 0F;
      onChanged();
      return this;
    }

    private double double_;

    /**
     * <code>optional double double = 12;</code>
     * 
     * @return Whether the double field is set.
     */
    @java.lang.Override
    public boolean hasDouble() {
      return ((bitField0_ & 0x00000800) != 0);
    }

    /**
     * <code>optional double double = 12;</code>
     * 
     * @return The double.
     */
    @java.lang.Override
    public double getDouble() {
      return double_;
    }

    /**
     * <code>optional double double = 12;</code>
     * 
     * @param value The double to set.
     * @return This builder for chaining.
     */
    public Builder setDouble(double value) {

      double_ = value;
      bitField0_ |= 0x00000800;
      onChanged();
      return this;
    }

    /**
     * <code>optional double double = 12;</code>
     * 
     * @return This builder for chaining.
     */
    public Builder clearDouble() {
      bitField0_ = (bitField0_ & ~0x00000800);
      double_ = 0D;
      onChanged();
      return this;
    }

    private boolean bool_;

    /**
     * <code>optional bool bool = 13;</code>
     * 
     * @return Whether the bool field is set.
     */
    @java.lang.Override
    public boolean hasBool() {
      return ((bitField0_ & 0x00001000) != 0);
    }

    /**
     * <code>optional bool bool = 13;</code>
     * 
     * @return The bool.
     */
    @java.lang.Override
    public boolean getBool() {
      return bool_;
    }

    /**
     * <code>optional bool bool = 13;</code>
     * 
     * @param value The bool to set.
     * @return This builder for chaining.
     */
    public Builder setBool(boolean value) {

      bool_ = value;
      bitField0_ |= 0x00001000;
      onChanged();
      return this;
    }

    /**
     * <code>optional bool bool = 13;</code>
     * 
     * @return This builder for chaining.
     */
    public Builder clearBool() {
      bitField0_ = (bitField0_ & ~0x00001000);
      bool_ = false;
      onChanged();
      return this;
    }

    private java.lang.Object string_ = "";

    /**
     * <code>optional string string = 14;</code>
     * 
     * @return Whether the string field is set.
     */
    public boolean hasString() {
      return ((bitField0_ & 0x00002000) != 0);
    }

    /**
     * <code>optional string string = 14;</code>
     * 
     * @return The string.
     */
    public java.lang.String getString() {
      java.lang.Object ref = string_;
      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()) {
          string_ = s;
        }
        return s;
      } else {
        return (java.lang.String) ref;
      }
    }

    /**
     * <code>optional string string = 14;</code>
     * 
     * @return The bytes for string.
     */
    public com.google.protobuf.ByteString getStringBytes() {
      java.lang.Object ref = string_;
      if (ref instanceof String) {
        com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8((java.lang.String) ref);
        string_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    /**
     * <code>optional string string = 14;</code>
     * 
     * @param value The string to set.
     * @return This builder for chaining.
     */
    public Builder setString(java.lang.String value) {
      if (value == null) {
        throw new NullPointerException();
      }
      string_ = value;
      bitField0_ |= 0x00002000;
      onChanged();
      return this;
    }

    /**
     * <code>optional string string = 14;</code>
     * 
     * @return This builder for chaining.
     */
    public Builder clearString() {
      string_ = getDefaultInstance().getString();
      bitField0_ = (bitField0_ & ~0x00002000);
      onChanged();
      return this;
    }

    /**
     * <code>optional string string = 14;</code>
     * 
     * @param value The bytes for string to set.
     * @return This builder for chaining.
     */
    public Builder setStringBytes(com.google.protobuf.ByteString value) {
      if (value == null) {
        throw new NullPointerException();
      }
      string_ = value;
      bitField0_ |= 0x00002000;
      onChanged();
      return this;
    }

    private com.google.protobuf.ByteString bytes_ = com.google.protobuf.ByteString.EMPTY;

    /**
     * <code>optional bytes bytes = 15;</code>
     * 
     * @return Whether the bytes field is set.
     */
    @java.lang.Override
    public boolean hasBytes() {
      return ((bitField0_ & 0x00004000) != 0);
    }

    /**
     * <code>optional bytes bytes = 15;</code>
     * 
     * @return The bytes.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString getBytes() {
      return bytes_;
    }

    /**
     * <code>optional bytes bytes = 15;</code>
     * 
     * @param value The bytes to set.
     * @return This builder for chaining.
     */
    public Builder setBytes(com.google.protobuf.ByteString value) {
      if (value == null) {
        throw new NullPointerException();
      }
      bytes_ = value;
      bitField0_ |= 0x00004000;
      onChanged();
      return this;
    }

    /**
     * <code>optional bytes bytes = 15;</code>
     * 
     * @return This builder for chaining.
     */
    public Builder clearBytes() {
      bitField0_ = (bitField0_ & ~0x00004000);
      bytes_ = getDefaultInstance().getBytes();
      onChanged();
      return this;
    }

    private int enum_ = 3;

    /**
     * <code>optional .org.apache.avro.protobuf.multiplefiles.A enum = 16 [default = Z];</code>
     * 
     * @return Whether the enum field is set.
     */
    @java.lang.Override
    public boolean hasEnum() {
      return ((bitField0_ & 0x00008000) != 0);
    }

    /**
     * <code>optional .org.apache.avro.protobuf.multiplefiles.A enum = 16 [default = Z];</code>
     * 
     * @return The enum.
     */
    @java.lang.Override
    public org.apache.avro.protobuf.multiplefiles.A getEnum() {
      org.apache.avro.protobuf.multiplefiles.A result = org.apache.avro.protobuf.multiplefiles.A.forNumber(enum_);
      return result == null ? org.apache.avro.protobuf.multiplefiles.A.Z : result;
    }

    /**
     * <code>optional .org.apache.avro.protobuf.multiplefiles.A enum = 16 [default = Z];</code>
     * 
     * @param value The enum to set.
     * @return This builder for chaining.
     */
    public Builder setEnum(org.apache.avro.protobuf.multiplefiles.A value) {
      if (value == null) {
        throw new NullPointerException();
      }
      bitField0_ |= 0x00008000;
      enum_ = value.getNumber();
      onChanged();
      return this;
    }

    /**
     * <code>optional .org.apache.avro.protobuf.multiplefiles.A enum = 16 [default = Z];</code>
     * 
     * @return This builder for chaining.
     */
    public Builder clearEnum() {
      bitField0_ = (bitField0_ & ~0x00008000);
      enum_ = 3;
      onChanged();
      return this;
    }

    private com.google.protobuf.Internal.IntList intArray_ = emptyIntList();

    private void ensureIntArrayIsMutable() {
      if (!intArray_.isModifiable()) {
        intArray_ = makeMutableCopy(intArray_);
      }
      bitField0_ |= 0x00010000;
    }

    /**
     * <pre>
     * some repeated types
     * </pre>
     *
     * <code>repeated int32 intArray = 17;</code>
     * 
     * @return A list containing the intArray.
     */
    public java.util.List<java.lang.Integer> getIntArrayList() {
      intArray_.makeImmutable();
      return intArray_;
    }

    /**
     * <pre>
     * some repeated types
     * </pre>
     *
     * <code>repeated int32 intArray = 17;</code>
     * 
     * @return The count of intArray.
     */
    public int getIntArrayCount() {
      return intArray_.size();
    }

    /**
     * <pre>
     * some repeated types
     * </pre>
     *
     * <code>repeated int32 intArray = 17;</code>
     * 
     * @param index The index of the element to return.
     * @return The intArray at the given index.
     */
    public int getIntArray(int index) {
      return intArray_.getInt(index);
    }

    /**
     * <pre>
     * some repeated types
     * </pre>
     *
     * <code>repeated int32 intArray = 17;</code>
     * 
     * @param index The index to set the value at.
     * @param value The intArray to set.
     * @return This builder for chaining.
     */
    public Builder setIntArray(int index, int value) {

      ensureIntArrayIsMutable();
      intArray_.setInt(index, value);
      bitField0_ |= 0x00010000;
      onChanged();
      return this;
    }

    /**
     * <pre>
     * some repeated types
     * </pre>
     *
     * <code>repeated int32 intArray = 17;</code>
     * 
     * @param value The intArray to add.
     * @return This builder for chaining.
     */
    public Builder addIntArray(int value) {

      ensureIntArrayIsMutable();
      intArray_.addInt(value);
      bitField0_ |= 0x00010000;
      onChanged();
      return this;
    }

    /**
     * <pre>
     * some repeated types
     * </pre>
     *
     * <code>repeated int32 intArray = 17;</code>
     * 
     * @param values The intArray to add.
     * @return This builder for chaining.
     */
    public Builder addAllIntArray(java.lang.Iterable<? extends java.lang.Integer> values) {
      ensureIntArrayIsMutable();
      com.google.protobuf.AbstractMessageLite.Builder.addAll(values, intArray_);
      bitField0_ |= 0x00010000;
      onChanged();
      return this;
    }

    /**
     * <pre>
     * some repeated types
     * </pre>
     *
     * <code>repeated int32 intArray = 17;</code>
     * 
     * @return This builder for chaining.
     */
    public Builder clearIntArray() {
      intArray_ = emptyIntList();
      bitField0_ = (bitField0_ & ~0x00010000);
      onChanged();
      return this;
    }

    private java.util.List<org.apache.avro.protobuf.multiplefiles.Foo> fooArray_ = java.util.Collections.emptyList();

    private void ensureFooArrayIsMutable() {
      if (!((bitField0_ & 0x00020000) != 0)) {
        fooArray_ = new java.util.ArrayList<org.apache.avro.protobuf.multiplefiles.Foo>(fooArray_);
        bitField0_ |= 0x00020000;
      }
    }

    private com.google.protobuf.RepeatedFieldBuilder<org.apache.avro.protobuf.multiplefiles.Foo, org.apache.avro.protobuf.multiplefiles.Foo.Builder, org.apache.avro.protobuf.multiplefiles.FooOrBuilder> fooArrayBuilder_;

    /**
     * <code>repeated .org.apache.avro.protobuf.multiplefiles.Foo fooArray = 20;</code>
     */
    public java.util.List<org.apache.avro.protobuf.multiplefiles.Foo> getFooArrayList() {
      if (fooArrayBuilder_ == null) {
        return java.util.Collections.unmodifiableList(fooArray_);
      } else {
        return fooArrayBuilder_.getMessageList();
      }
    }

    /**
     * <code>repeated .org.apache.avro.protobuf.multiplefiles.Foo fooArray = 20;</code>
     */
    public int getFooArrayCount() {
      if (fooArrayBuilder_ == null) {
        return fooArray_.size();
      } else {
        return fooArrayBuilder_.getCount();
      }
    }

    /**
     * <code>repeated .org.apache.avro.protobuf.multiplefiles.Foo fooArray = 20;</code>
     */
    public org.apache.avro.protobuf.multiplefiles.Foo getFooArray(int index) {
      if (fooArrayBuilder_ == null) {
        return fooArray_.get(index);
      } else {
        return fooArrayBuilder_.getMessage(index);
      }
    }

    /**
     * <code>repeated .org.apache.avro.protobuf.multiplefiles.Foo fooArray = 20;</code>
     */
    public Builder setFooArray(int index, org.apache.avro.protobuf.multiplefiles.Foo value) {
      if (fooArrayBuilder_ == null) {
        if (value == null) {
          throw new NullPointerException();
        }
        ensureFooArrayIsMutable();
        fooArray_.set(index, value);
        onChanged();
      } else {
        fooArrayBuilder_.setMessage(index, value);
      }
      return this;
    }

    /**
     * <code>repeated .org.apache.avro.protobuf.multiplefiles.Foo fooArray = 20;</code>
     */
    public Builder setFooArray(int index, org.apache.avro.protobuf.multiplefiles.Foo.Builder builderForValue) {
      if (fooArrayBuilder_ == null) {
        ensureFooArrayIsMutable();
        fooArray_.set(index, builderForValue.build());
        onChanged();
      } else {
        fooArrayBuilder_.setMessage(index, builderForValue.build());
      }
      return this;
    }

    /**
     * <code>repeated .org.apache.avro.protobuf.multiplefiles.Foo fooArray = 20;</code>
     */
    public Builder addFooArray(org.apache.avro.protobuf.multiplefiles.Foo value) {
      if (fooArrayBuilder_ == null) {
        if (value == null) {
          throw new NullPointerException();
        }
        ensureFooArrayIsMutable();
        fooArray_.add(value);
        onChanged();
      } else {
        fooArrayBuilder_.addMessage(value);
      }
      return this;
    }

    /**
     * <code>repeated .org.apache.avro.protobuf.multiplefiles.Foo fooArray = 20;</code>
     */
    public Builder addFooArray(int index, org.apache.avro.protobuf.multiplefiles.Foo value) {
      if (fooArrayBuilder_ == null) {
        if (value == null) {
          throw new NullPointerException();
        }
        ensureFooArrayIsMutable();
        fooArray_.add(index, value);
        onChanged();
      } else {
        fooArrayBuilder_.addMessage(index, value);
      }
      return this;
    }

    /**
     * <code>repeated .org.apache.avro.protobuf.multiplefiles.Foo fooArray = 20;</code>
     */
    public Builder addFooArray(org.apache.avro.protobuf.multiplefiles.Foo.Builder builderForValue) {
      if (fooArrayBuilder_ == null) {
        ensureFooArrayIsMutable();
        fooArray_.add(builderForValue.build());
        onChanged();
      } else {
        fooArrayBuilder_.addMessage(builderForValue.build());
      }
      return this;
    }

    /**
     * <code>repeated .org.apache.avro.protobuf.multiplefiles.Foo fooArray = 20;</code>
     */
    public Builder addFooArray(int index, org.apache.avro.protobuf.multiplefiles.Foo.Builder builderForValue) {
      if (fooArrayBuilder_ == null) {
        ensureFooArrayIsMutable();
        fooArray_.add(index, builderForValue.build());
        onChanged();
      } else {
        fooArrayBuilder_.addMessage(index, builderForValue.build());
      }
      return this;
    }

    /**
     * <code>repeated .org.apache.avro.protobuf.multiplefiles.Foo fooArray = 20;</code>
     */
    public Builder addAllFooArray(java.lang.Iterable<? extends org.apache.avro.protobuf.multiplefiles.Foo> values) {
      if (fooArrayBuilder_ == null) {
        ensureFooArrayIsMutable();
        com.google.protobuf.AbstractMessageLite.Builder.addAll(values, fooArray_);
        onChanged();
      } else {
        fooArrayBuilder_.addAllMessages(values);
      }
      return this;
    }

    /**
     * <code>repeated .org.apache.avro.protobuf.multiplefiles.Foo fooArray = 20;</code>
     */
    public Builder clearFooArray() {
      if (fooArrayBuilder_ == null) {
        fooArray_ = java.util.Collections.emptyList();
        bitField0_ = (bitField0_ & ~0x00020000);
        onChanged();
      } else {
        fooArrayBuilder_.clear();
      }
      return this;
    }

    /**
     * <code>repeated .org.apache.avro.protobuf.multiplefiles.Foo fooArray = 20;</code>
     */
    public Builder removeFooArray(int index) {
      if (fooArrayBuilder_ == null) {
        ensureFooArrayIsMutable();
        fooArray_.remove(index);
        onChanged();
      } else {
        fooArrayBuilder_.remove(index);
      }
      return this;
    }

    /**
     * <code>repeated .org.apache.avro.protobuf.multiplefiles.Foo fooArray = 20;</code>
     */
    public org.apache.avro.protobuf.multiplefiles.Foo.Builder getFooArrayBuilder(int index) {
      return getFooArrayFieldBuilder().getBuilder(index);
    }

    /**
     * <code>repeated .org.apache.avro.protobuf.multiplefiles.Foo fooArray = 20;</code>
     */
    public org.apache.avro.protobuf.multiplefiles.FooOrBuilder getFooArrayOrBuilder(int index) {
      if (fooArrayBuilder_ == null) {
        return fooArray_.get(index);
      } else {
        return fooArrayBuilder_.getMessageOrBuilder(index);
      }
    }

    /**
     * <code>repeated .org.apache.avro.protobuf.multiplefiles.Foo fooArray = 20;</code>
     */
    public java.util.List<? extends org.apache.avro.protobuf.multiplefiles.FooOrBuilder> getFooArrayOrBuilderList() {
      if (fooArrayBuilder_ != null) {
        return fooArrayBuilder_.getMessageOrBuilderList();
      } else {
        return java.util.Collections.unmodifiableList(fooArray_);
      }
    }

    /**
     * <code>repeated .org.apache.avro.protobuf.multiplefiles.Foo fooArray = 20;</code>
     */
    public org.apache.avro.protobuf.multiplefiles.Foo.Builder addFooArrayBuilder() {
      return getFooArrayFieldBuilder().addBuilder(org.apache.avro.protobuf.multiplefiles.Foo.getDefaultInstance());
    }

    /**
     * <code>repeated .org.apache.avro.protobuf.multiplefiles.Foo fooArray = 20;</code>
     */
    public org.apache.avro.protobuf.multiplefiles.Foo.Builder addFooArrayBuilder(int index) {
      return getFooArrayFieldBuilder().addBuilder(index,
          org.apache.avro.protobuf.multiplefiles.Foo.getDefaultInstance());
    }

    /**
     * <code>repeated .org.apache.avro.protobuf.multiplefiles.Foo fooArray = 20;</code>
     */
    public java.util.List<org.apache.avro.protobuf.multiplefiles.Foo.Builder> getFooArrayBuilderList() {
      return getFooArrayFieldBuilder().getBuilderList();
    }

    private com.google.protobuf.RepeatedFieldBuilder<org.apache.avro.protobuf.multiplefiles.Foo, org.apache.avro.protobuf.multiplefiles.Foo.Builder, org.apache.avro.protobuf.multiplefiles.FooOrBuilder> getFooArrayFieldBuilder() {
      if (fooArrayBuilder_ == null) {
        fooArrayBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<org.apache.avro.protobuf.multiplefiles.Foo, org.apache.avro.protobuf.multiplefiles.Foo.Builder, org.apache.avro.protobuf.multiplefiles.FooOrBuilder>(
            fooArray_, ((bitField0_ & 0x00020000) != 0), getParentForChildren(), isClean());
        fooArray_ = null;
      }
      return fooArrayBuilder_;
    }

    private java.util.List<java.lang.Integer> syms_ = java.util.Collections.emptyList();

    private void ensureSymsIsMutable() {
      if (!((bitField0_ & 0x00040000) != 0)) {
        syms_ = new java.util.ArrayList<java.lang.Integer>(syms_);
        bitField0_ |= 0x00040000;
      }
    }

    /**
     * <code>repeated .org.apache.avro.protobuf.multiplefiles.A syms = 19;</code>
     * 
     * @return A list containing the syms.
     */
    public java.util.List<org.apache.avro.protobuf.multiplefiles.A> getSymsList() {
      return new com.google.protobuf.Internal.ListAdapter<java.lang.Integer, org.apache.avro.protobuf.multiplefiles.A>(
          syms_, syms_converter_);
    }

    /**
     * <code>repeated .org.apache.avro.protobuf.multiplefiles.A syms = 19;</code>
     * 
     * @return The count of syms.
     */
    public int getSymsCount() {
      return syms_.size();
    }

    /**
     * <code>repeated .org.apache.avro.protobuf.multiplefiles.A syms = 19;</code>
     * 
     * @param index The index of the element to return.
     * @return The syms at the given index.
     */
    public org.apache.avro.protobuf.multiplefiles.A getSyms(int index) {
      return syms_converter_.convert(syms_.get(index));
    }

    /**
     * <code>repeated .org.apache.avro.protobuf.multiplefiles.A syms = 19;</code>
     * 
     * @param index The index to set the value at.
     * @param value The syms to set.
     * @return This builder for chaining.
     */
    public Builder setSyms(int index, org.apache.avro.protobuf.multiplefiles.A value) {
      if (value == null) {
        throw new NullPointerException();
      }
      ensureSymsIsMutable();
      syms_.set(index, value.getNumber());
      onChanged();
      return this;
    }

    /**
     * <code>repeated .org.apache.avro.protobuf.multiplefiles.A syms = 19;</code>
     * 
     * @param value The syms to add.
     * @return This builder for chaining.
     */
    public Builder addSyms(org.apache.avro.protobuf.multiplefiles.A value) {
      if (value == null) {
        throw new NullPointerException();
      }
      ensureSymsIsMutable();
      syms_.add(value.getNumber());
      onChanged();
      return this;
    }

    /**
     * <code>repeated .org.apache.avro.protobuf.multiplefiles.A syms = 19;</code>
     * 
     * @param values The syms to add.
     * @return This builder for chaining.
     */
    public Builder addAllSyms(java.lang.Iterable<? extends org.apache.avro.protobuf.multiplefiles.A> values) {
      ensureSymsIsMutable();
      for (org.apache.avro.protobuf.multiplefiles.A value : values) {
        syms_.add(value.getNumber());
      }
      onChanged();
      return this;
    }

    /**
     * <code>repeated .org.apache.avro.protobuf.multiplefiles.A syms = 19;</code>
     * 
     * @return This builder for chaining.
     */
    public Builder clearSyms() {
      syms_ = java.util.Collections.emptyList();
      bitField0_ = (bitField0_ & ~0x00040000);
      onChanged();
      return this;
    }

    private org.apache.avro.protobuf.multiplefiles.Foo foo_;
    private com.google.protobuf.SingleFieldBuilder<org.apache.avro.protobuf.multiplefiles.Foo, org.apache.avro.protobuf.multiplefiles.Foo.Builder, org.apache.avro.protobuf.multiplefiles.FooOrBuilder> fooBuilder_;

    /**
     * <pre>
     * a recursive type
     * </pre>
     *
     * <code>optional .org.apache.avro.protobuf.multiplefiles.Foo foo = 18;</code>
     * 
     * @return Whether the foo field is set.
     */
    public boolean hasFoo() {
      return ((bitField0_ & 0x00080000) != 0);
    }

    /**
     * <pre>
     * a recursive type
     * </pre>
     *
     * <code>optional .org.apache.avro.protobuf.multiplefiles.Foo foo = 18;</code>
     * 
     * @return The foo.
     */
    public org.apache.avro.protobuf.multiplefiles.Foo getFoo() {
      if (fooBuilder_ == null) {
        return foo_ == null ? org.apache.avro.protobuf.multiplefiles.Foo.getDefaultInstance() : foo_;
      } else {
        return fooBuilder_.getMessage();
      }
    }

    /**
     * <pre>
     * a recursive type
     * </pre>
     *
     * <code>optional .org.apache.avro.protobuf.multiplefiles.Foo foo = 18;</code>
     */
    public Builder setFoo(org.apache.avro.protobuf.multiplefiles.Foo value) {
      if (fooBuilder_ == null) {
        if (value == null) {
          throw new NullPointerException();
        }
        foo_ = value;
      } else {
        fooBuilder_.setMessage(value);
      }
      bitField0_ |= 0x00080000;
      onChanged();
      return this;
    }

    /**
     * <pre>
     * a recursive type
     * </pre>
     *
     * <code>optional .org.apache.avro.protobuf.multiplefiles.Foo foo = 18;</code>
     */
    public Builder setFoo(org.apache.avro.protobuf.multiplefiles.Foo.Builder builderForValue) {
      if (fooBuilder_ == null) {
        foo_ = builderForValue.build();
      } else {
        fooBuilder_.setMessage(builderForValue.build());
      }
      bitField0_ |= 0x00080000;
      onChanged();
      return this;
    }

    /**
     * <pre>
     * a recursive type
     * </pre>
     *
     * <code>optional .org.apache.avro.protobuf.multiplefiles.Foo foo = 18;</code>
     */
    public Builder mergeFoo(org.apache.avro.protobuf.multiplefiles.Foo value) {
      if (fooBuilder_ == null) {
        if (((bitField0_ & 0x00080000) != 0) && foo_ != null
            && foo_ != org.apache.avro.protobuf.multiplefiles.Foo.getDefaultInstance()) {
          getFooBuilder().mergeFrom(value);
        } else {
          foo_ = value;
        }
      } else {
        fooBuilder_.mergeFrom(value);
      }
      if (foo_ != null) {
        bitField0_ |= 0x00080000;
        onChanged();
      }
      return this;
    }

    /**
     * <pre>
     * a recursive type
     * </pre>
     *
     * <code>optional .org.apache.avro.protobuf.multiplefiles.Foo foo = 18;</code>
     */
    public Builder clearFoo() {
      bitField0_ = (bitField0_ & ~0x00080000);
      foo_ = null;
      if (fooBuilder_ != null) {
        fooBuilder_.dispose();
        fooBuilder_ = null;
      }
      onChanged();
      return this;
    }

    /**
     * <pre>
     * a recursive type
     * </pre>
     *
     * <code>optional .org.apache.avro.protobuf.multiplefiles.Foo foo = 18;</code>
     */
    public org.apache.avro.protobuf.multiplefiles.Foo.Builder getFooBuilder() {
      bitField0_ |= 0x00080000;
      onChanged();
      return getFooFieldBuilder().getBuilder();
    }

    /**
     * <pre>
     * a recursive type
     * </pre>
     *
     * <code>optional .org.apache.avro.protobuf.multiplefiles.Foo foo = 18;</code>
     */
    public org.apache.avro.protobuf.multiplefiles.FooOrBuilder getFooOrBuilder() {
      if (fooBuilder_ != null) {
        return fooBuilder_.getMessageOrBuilder();
      } else {
        return foo_ == null ? org.apache.avro.protobuf.multiplefiles.Foo.getDefaultInstance() : foo_;
      }
    }

    /**
     * <pre>
     * a recursive type
     * </pre>
     *
     * <code>optional .org.apache.avro.protobuf.multiplefiles.Foo foo = 18;</code>
     */
    private com.google.protobuf.SingleFieldBuilder<org.apache.avro.protobuf.multiplefiles.Foo, org.apache.avro.protobuf.multiplefiles.Foo.Builder, org.apache.avro.protobuf.multiplefiles.FooOrBuilder> getFooFieldBuilder() {
      if (fooBuilder_ == null) {
        fooBuilder_ = new com.google.protobuf.SingleFieldBuilder<org.apache.avro.protobuf.multiplefiles.Foo, org.apache.avro.protobuf.multiplefiles.Foo.Builder, org.apache.avro.protobuf.multiplefiles.FooOrBuilder>(
            getFoo(), getParentForChildren(), isClean());
        foo_ = null;
      }
      return fooBuilder_;
    }

    private com.google.protobuf.Timestamp timestamp_;
    private com.google.protobuf.SingleFieldBuilder<com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> timestampBuilder_;

    /**
     * <pre>
     * a predefined message type
     * </pre>
     *
     * <code>optional .google.protobuf.Timestamp timestamp = 21;</code>
     * 
     * @return Whether the timestamp field is set.
     */
    public boolean hasTimestamp() {
      return ((bitField0_ & 0x00100000) != 0);
    }

    /**
     * <pre>
     * a predefined message type
     * </pre>
     *
     * <code>optional .google.protobuf.Timestamp timestamp = 21;</code>
     * 
     * @return The timestamp.
     */
    public com.google.protobuf.Timestamp getTimestamp() {
      if (timestampBuilder_ == null) {
        return timestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : timestamp_;
      } else {
        return timestampBuilder_.getMessage();
      }
    }

    /**
     * <pre>
     * a predefined message type
     * </pre>
     *
     * <code>optional .google.protobuf.Timestamp timestamp = 21;</code>
     */
    public Builder setTimestamp(com.google.protobuf.Timestamp value) {
      if (timestampBuilder_ == null) {
        if (value == null) {
          throw new NullPointerException();
        }
        timestamp_ = value;
      } else {
        timestampBuilder_.setMessage(value);
      }
      bitField0_ |= 0x00100000;
      onChanged();
      return this;
    }

    /**
     * <pre>
     * a predefined message type
     * </pre>
     *
     * <code>optional .google.protobuf.Timestamp timestamp = 21;</code>
     */
    public Builder setTimestamp(com.google.protobuf.Timestamp.Builder builderForValue) {
      if (timestampBuilder_ == null) {
        timestamp_ = builderForValue.build();
      } else {
        timestampBuilder_.setMessage(builderForValue.build());
      }
      bitField0_ |= 0x00100000;
      onChanged();
      return this;
    }

    /**
     * <pre>
     * a predefined message type
     * </pre>
     *
     * <code>optional .google.protobuf.Timestamp timestamp = 21;</code>
     */
    public Builder mergeTimestamp(com.google.protobuf.Timestamp value) {
      if (timestampBuilder_ == null) {
        if (((bitField0_ & 0x00100000) != 0) && timestamp_ != null
            && timestamp_ != com.google.protobuf.Timestamp.getDefaultInstance()) {
          getTimestampBuilder().mergeFrom(value);
        } else {
          timestamp_ = value;
        }
      } else {
        timestampBuilder_.mergeFrom(value);
      }
      if (timestamp_ != null) {
        bitField0_ |= 0x00100000;
        onChanged();
      }
      return this;
    }

    /**
     * <pre>
     * a predefined message type
     * </pre>
     *
     * <code>optional .google.protobuf.Timestamp timestamp = 21;</code>
     */
    public Builder clearTimestamp() {
      bitField0_ = (bitField0_ & ~0x00100000);
      timestamp_ = null;
      if (timestampBuilder_ != null) {
        timestampBuilder_.dispose();
        timestampBuilder_ = null;
      }
      onChanged();
      return this;
    }

    /**
     * <pre>
     * a predefined message type
     * </pre>
     *
     * <code>optional .google.protobuf.Timestamp timestamp = 21;</code>
     */
    public com.google.protobuf.Timestamp.Builder getTimestampBuilder() {
      bitField0_ |= 0x00100000;
      onChanged();
      return getTimestampFieldBuilder().getBuilder();
    }

    /**
     * <pre>
     * a predefined message type
     * </pre>
     *
     * <code>optional .google.protobuf.Timestamp timestamp = 21;</code>
     */
    public com.google.protobuf.TimestampOrBuilder getTimestampOrBuilder() {
      if (timestampBuilder_ != null) {
        return timestampBuilder_.getMessageOrBuilder();
      } else {
        return timestamp_ == null ? com.google.protobuf.Timestamp.getDefaultInstance() : timestamp_;
      }
    }

    /**
     * <pre>
     * a predefined message type
     * </pre>
     *
     * <code>optional .google.protobuf.Timestamp timestamp = 21;</code>
     */
    private com.google.protobuf.SingleFieldBuilder<com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder> getTimestampFieldBuilder() {
      if (timestampBuilder_ == null) {
        timestampBuilder_ = new com.google.protobuf.SingleFieldBuilder<com.google.protobuf.Timestamp, com.google.protobuf.Timestamp.Builder, com.google.protobuf.TimestampOrBuilder>(
            getTimestamp(), getParentForChildren(), isClean());
        timestamp_ = null;
      }
      return timestampBuilder_;
    }

    // @@protoc_insertion_point(builder_scope:org.apache.avro.protobuf.multiplefiles.Foo)
  }

  // @@protoc_insertion_point(class_scope:org.apache.avro.protobuf.multiplefiles.Foo)
  private static final org.apache.avro.protobuf.multiplefiles.Foo DEFAULT_INSTANCE;
  static {
    DEFAULT_INSTANCE = new org.apache.avro.protobuf.multiplefiles.Foo();
  }

  public static org.apache.avro.protobuf.multiplefiles.Foo getDefaultInstance() {
    return DEFAULT_INSTANCE;
  }

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

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

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

  @java.lang.Override
  public org.apache.avro.protobuf.multiplefiles.Foo getDefaultInstanceForType() {
    return DEFAULT_INSTANCE;
  }

}
