// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: Span.proto

package org.apache.htrace.protobuf.generated;

public final class SpanProtos {
  private SpanProtos() {}
  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistry registry) {
  }
  public interface TimelineAnnotationOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required int64 time = 1;
    /**
     * <code>required int64 time = 1;</code>
     */
    boolean hasTime();
    /**
     * <code>required int64 time = 1;</code>
     */
    long getTime();

    // required string message = 2;
    /**
     * <code>required string message = 2;</code>
     */
    boolean hasMessage();
    /**
     * <code>required string message = 2;</code>
     */
    java.lang.String getMessage();
    /**
     * <code>required string message = 2;</code>
     */
    com.google.protobuf.ByteString
        getMessageBytes();
  }
  /**
   * Protobuf type {@code TimelineAnnotation}
   */
  public static final class TimelineAnnotation extends
      com.google.protobuf.GeneratedMessage
      implements TimelineAnnotationOrBuilder {
    // Use TimelineAnnotation.newBuilder() to construct.
    private TimelineAnnotation(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private TimelineAnnotation(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final TimelineAnnotation defaultInstance;
    public static TimelineAnnotation getDefaultInstance() {
      return defaultInstance;
    }

    public TimelineAnnotation getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private TimelineAnnotation(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              time_ = input.readInt64();
              break;
            }
            case 18: {
              bitField0_ |= 0x00000002;
              message_ = input.readBytes();
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.htrace.protobuf.generated.SpanProtos.internal_static_TimelineAnnotation_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.htrace.protobuf.generated.SpanProtos.internal_static_TimelineAnnotation_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation.class, org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation.Builder.class);
    }

    public static com.google.protobuf.Parser<TimelineAnnotation> PARSER =
        new com.google.protobuf.AbstractParser<TimelineAnnotation>() {
      public TimelineAnnotation parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new TimelineAnnotation(input, extensionRegistry);
      }
    };

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

    private int bitField0_;
    // required int64 time = 1;
    public static final int TIME_FIELD_NUMBER = 1;
    private long time_;
    /**
     * <code>required int64 time = 1;</code>
     */
    public boolean hasTime() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int64 time = 1;</code>
     */
    public long getTime() {
      return time_;
    }

    // required string message = 2;
    public static final int MESSAGE_FIELD_NUMBER = 2;
    private java.lang.Object message_;
    /**
     * <code>required string message = 2;</code>
     */
    public boolean hasMessage() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required string message = 2;</code>
     */
    public java.lang.String getMessage() {
      java.lang.Object ref = message_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          message_ = s;
        }
        return s;
      }
    }
    /**
     * <code>required string message = 2;</code>
     */
    public com.google.protobuf.ByteString
        getMessageBytes() {
      java.lang.Object ref = message_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        message_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    private void initFields() {
      time_ = 0L;
      message_ = "";
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

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

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt64(1, time_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeBytes(2, getMessageBytes());
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(1, time_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(2, getMessageBytes());
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

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

      boolean result = true;
      result = result && (hasTime() == other.hasTime());
      if (hasTime()) {
        result = result && (getTime()
            == other.getTime());
      }
      result = result && (hasMessage() == other.hasMessage());
      if (hasMessage()) {
        result = result && getMessage()
            .equals(other.getMessage());
      }
      result = result &&
          getUnknownFields().equals(other.getUnknownFields());
      return result;
    }

    private int memoizedHashCode = 0;
    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptorForType().hashCode();
      if (hasTime()) {
        hash = (37 * hash) + TIME_FIELD_NUMBER;
        hash = (53 * hash) + hashLong(getTime());
      }
      if (hasMessage()) {
        hash = (37 * hash) + MESSAGE_FIELD_NUMBER;
        hash = (53 * hash) + getMessage().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation 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.htrace.protobuf.generated.SpanProtos.TimelineAnnotation parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code TimelineAnnotation}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotationOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.htrace.protobuf.generated.SpanProtos.internal_static_TimelineAnnotation_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.htrace.protobuf.generated.SpanProtos.internal_static_TimelineAnnotation_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation.class, org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation.Builder.class);
      }

      // Construct using org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        time_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000001);
        message_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.htrace.protobuf.generated.SpanProtos.internal_static_TimelineAnnotation_descriptor;
      }

      public org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation getDefaultInstanceForType() {
        return org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation.getDefaultInstance();
      }

      public org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation build() {
        org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation buildPartial() {
        org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation result = new org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.time_ = time_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.message_ = message_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation) {
          return mergeFrom((org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation other) {
        if (other == org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation.getDefaultInstance()) return this;
        if (other.hasTime()) {
          setTime(other.getTime());
        }
        if (other.hasMessage()) {
          bitField0_ |= 0x00000002;
          message_ = other.message_;
          onChanged();
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasTime()) {
          
          return false;
        }
        if (!hasMessage()) {
          
          return false;
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required int64 time = 1;
      private long time_ ;
      /**
       * <code>required int64 time = 1;</code>
       */
      public boolean hasTime() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int64 time = 1;</code>
       */
      public long getTime() {
        return time_;
      }
      /**
       * <code>required int64 time = 1;</code>
       */
      public Builder setTime(long value) {
        bitField0_ |= 0x00000001;
        time_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 time = 1;</code>
       */
      public Builder clearTime() {
        bitField0_ = (bitField0_ & ~0x00000001);
        time_ = 0L;
        onChanged();
        return this;
      }

      // required string message = 2;
      private java.lang.Object message_ = "";
      /**
       * <code>required string message = 2;</code>
       */
      public boolean hasMessage() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required string message = 2;</code>
       */
      public java.lang.String getMessage() {
        java.lang.Object ref = message_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          message_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>required string message = 2;</code>
       */
      public com.google.protobuf.ByteString
          getMessageBytes() {
        java.lang.Object ref = message_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          message_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>required string message = 2;</code>
       */
      public Builder setMessage(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        message_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required string message = 2;</code>
       */
      public Builder clearMessage() {
        bitField0_ = (bitField0_ & ~0x00000002);
        message_ = getDefaultInstance().getMessage();
        onChanged();
        return this;
      }
      /**
       * <code>required string message = 2;</code>
       */
      public Builder setMessageBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        message_ = value;
        onChanged();
        return this;
      }

      // @@protoc_insertion_point(builder_scope:TimelineAnnotation)
    }

    static {
      defaultInstance = new TimelineAnnotation(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:TimelineAnnotation)
  }

  public interface SpanOrBuilder
      extends com.google.protobuf.MessageOrBuilder {

    // required int64 trace_id = 1;
    /**
     * <code>required int64 trace_id = 1;</code>
     */
    boolean hasTraceId();
    /**
     * <code>required int64 trace_id = 1;</code>
     */
    long getTraceId();

    // required int64 parent_id = 2;
    /**
     * <code>required int64 parent_id = 2;</code>
     */
    boolean hasParentId();
    /**
     * <code>required int64 parent_id = 2;</code>
     */
    long getParentId();

    // required int64 start = 3;
    /**
     * <code>required int64 start = 3;</code>
     */
    boolean hasStart();
    /**
     * <code>required int64 start = 3;</code>
     */
    long getStart();

    // required int64 stop = 4;
    /**
     * <code>required int64 stop = 4;</code>
     */
    boolean hasStop();
    /**
     * <code>required int64 stop = 4;</code>
     */
    long getStop();

    // required int64 span_id = 5;
    /**
     * <code>required int64 span_id = 5;</code>
     */
    boolean hasSpanId();
    /**
     * <code>required int64 span_id = 5;</code>
     */
    long getSpanId();

    // required string process_id = 6;
    /**
     * <code>required string process_id = 6;</code>
     */
    boolean hasProcessId();
    /**
     * <code>required string process_id = 6;</code>
     */
    java.lang.String getProcessId();
    /**
     * <code>required string process_id = 6;</code>
     */
    com.google.protobuf.ByteString
        getProcessIdBytes();

    // required string description = 7;
    /**
     * <code>required string description = 7;</code>
     */
    boolean hasDescription();
    /**
     * <code>required string description = 7;</code>
     */
    java.lang.String getDescription();
    /**
     * <code>required string description = 7;</code>
     */
    com.google.protobuf.ByteString
        getDescriptionBytes();

    // repeated .TimelineAnnotation timeline = 8;
    /**
     * <code>repeated .TimelineAnnotation timeline = 8;</code>
     */
    java.util.List<org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation> 
        getTimelineList();
    /**
     * <code>repeated .TimelineAnnotation timeline = 8;</code>
     */
    org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation getTimeline(int index);
    /**
     * <code>repeated .TimelineAnnotation timeline = 8;</code>
     */
    int getTimelineCount();
    /**
     * <code>repeated .TimelineAnnotation timeline = 8;</code>
     */
    java.util.List<? extends org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotationOrBuilder> 
        getTimelineOrBuilderList();
    /**
     * <code>repeated .TimelineAnnotation timeline = 8;</code>
     */
    org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotationOrBuilder getTimelineOrBuilder(
        int index);
  }
  /**
   * Protobuf type {@code Span}
   */
  public static final class Span extends
      com.google.protobuf.GeneratedMessage
      implements SpanOrBuilder {
    // Use Span.newBuilder() to construct.
    private Span(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
      super(builder);
      this.unknownFields = builder.getUnknownFields();
    }
    private Span(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }

    private static final Span defaultInstance;
    public static Span getDefaultInstance() {
      return defaultInstance;
    }

    public Span getDefaultInstanceForType() {
      return defaultInstance;
    }

    private final com.google.protobuf.UnknownFieldSet unknownFields;
    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
        getUnknownFields() {
      return this.unknownFields;
    }
    private Span(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      initFields();
      int mutable_bitField0_ = 0;
      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
          com.google.protobuf.UnknownFieldSet.newBuilder();
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            default: {
              if (!parseUnknownField(input, unknownFields,
                                     extensionRegistry, tag)) {
                done = true;
              }
              break;
            }
            case 8: {
              bitField0_ |= 0x00000001;
              traceId_ = input.readInt64();
              break;
            }
            case 16: {
              bitField0_ |= 0x00000002;
              parentId_ = input.readInt64();
              break;
            }
            case 24: {
              bitField0_ |= 0x00000004;
              start_ = input.readInt64();
              break;
            }
            case 32: {
              bitField0_ |= 0x00000008;
              stop_ = input.readInt64();
              break;
            }
            case 40: {
              bitField0_ |= 0x00000010;
              spanId_ = input.readInt64();
              break;
            }
            case 50: {
              bitField0_ |= 0x00000020;
              processId_ = input.readBytes();
              break;
            }
            case 58: {
              bitField0_ |= 0x00000040;
              description_ = input.readBytes();
              break;
            }
            case 66: {
              if (!((mutable_bitField0_ & 0x00000080) == 0x00000080)) {
                timeline_ = new java.util.ArrayList<org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation>();
                mutable_bitField0_ |= 0x00000080;
              }
              timeline_.add(input.readMessage(org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation.PARSER, extensionRegistry));
              break;
            }
          }
        }
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.setUnfinishedMessage(this);
      } catch (java.io.IOException e) {
        throw new com.google.protobuf.InvalidProtocolBufferException(
            e.getMessage()).setUnfinishedMessage(this);
      } finally {
        if (((mutable_bitField0_ & 0x00000080) == 0x00000080)) {
          timeline_ = java.util.Collections.unmodifiableList(timeline_);
        }
        this.unknownFields = unknownFields.build();
        makeExtensionsImmutable();
      }
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.htrace.protobuf.generated.SpanProtos.internal_static_Span_descriptor;
    }

    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.htrace.protobuf.generated.SpanProtos.internal_static_Span_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.htrace.protobuf.generated.SpanProtos.Span.class, org.apache.htrace.protobuf.generated.SpanProtos.Span.Builder.class);
    }

    public static com.google.protobuf.Parser<Span> PARSER =
        new com.google.protobuf.AbstractParser<Span>() {
      public Span parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        return new Span(input, extensionRegistry);
      }
    };

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

    private int bitField0_;
    // required int64 trace_id = 1;
    public static final int TRACE_ID_FIELD_NUMBER = 1;
    private long traceId_;
    /**
     * <code>required int64 trace_id = 1;</code>
     */
    public boolean hasTraceId() {
      return ((bitField0_ & 0x00000001) == 0x00000001);
    }
    /**
     * <code>required int64 trace_id = 1;</code>
     */
    public long getTraceId() {
      return traceId_;
    }

    // required int64 parent_id = 2;
    public static final int PARENT_ID_FIELD_NUMBER = 2;
    private long parentId_;
    /**
     * <code>required int64 parent_id = 2;</code>
     */
    public boolean hasParentId() {
      return ((bitField0_ & 0x00000002) == 0x00000002);
    }
    /**
     * <code>required int64 parent_id = 2;</code>
     */
    public long getParentId() {
      return parentId_;
    }

    // required int64 start = 3;
    public static final int START_FIELD_NUMBER = 3;
    private long start_;
    /**
     * <code>required int64 start = 3;</code>
     */
    public boolean hasStart() {
      return ((bitField0_ & 0x00000004) == 0x00000004);
    }
    /**
     * <code>required int64 start = 3;</code>
     */
    public long getStart() {
      return start_;
    }

    // required int64 stop = 4;
    public static final int STOP_FIELD_NUMBER = 4;
    private long stop_;
    /**
     * <code>required int64 stop = 4;</code>
     */
    public boolean hasStop() {
      return ((bitField0_ & 0x00000008) == 0x00000008);
    }
    /**
     * <code>required int64 stop = 4;</code>
     */
    public long getStop() {
      return stop_;
    }

    // required int64 span_id = 5;
    public static final int SPAN_ID_FIELD_NUMBER = 5;
    private long spanId_;
    /**
     * <code>required int64 span_id = 5;</code>
     */
    public boolean hasSpanId() {
      return ((bitField0_ & 0x00000010) == 0x00000010);
    }
    /**
     * <code>required int64 span_id = 5;</code>
     */
    public long getSpanId() {
      return spanId_;
    }

    // required string process_id = 6;
    public static final int PROCESS_ID_FIELD_NUMBER = 6;
    private java.lang.Object processId_;
    /**
     * <code>required string process_id = 6;</code>
     */
    public boolean hasProcessId() {
      return ((bitField0_ & 0x00000020) == 0x00000020);
    }
    /**
     * <code>required string process_id = 6;</code>
     */
    public java.lang.String getProcessId() {
      java.lang.Object ref = processId_;
      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()) {
          processId_ = s;
        }
        return s;
      }
    }
    /**
     * <code>required string process_id = 6;</code>
     */
    public com.google.protobuf.ByteString
        getProcessIdBytes() {
      java.lang.Object ref = processId_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        processId_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // required string description = 7;
    public static final int DESCRIPTION_FIELD_NUMBER = 7;
    private java.lang.Object description_;
    /**
     * <code>required string description = 7;</code>
     */
    public boolean hasDescription() {
      return ((bitField0_ & 0x00000040) == 0x00000040);
    }
    /**
     * <code>required string description = 7;</code>
     */
    public java.lang.String getDescription() {
      java.lang.Object ref = description_;
      if (ref instanceof java.lang.String) {
        return (java.lang.String) ref;
      } else {
        com.google.protobuf.ByteString bs = 
            (com.google.protobuf.ByteString) ref;
        java.lang.String s = bs.toStringUtf8();
        if (bs.isValidUtf8()) {
          description_ = s;
        }
        return s;
      }
    }
    /**
     * <code>required string description = 7;</code>
     */
    public com.google.protobuf.ByteString
        getDescriptionBytes() {
      java.lang.Object ref = description_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        description_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    // repeated .TimelineAnnotation timeline = 8;
    public static final int TIMELINE_FIELD_NUMBER = 8;
    private java.util.List<org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation> timeline_;
    /**
     * <code>repeated .TimelineAnnotation timeline = 8;</code>
     */
    public java.util.List<org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation> getTimelineList() {
      return timeline_;
    }
    /**
     * <code>repeated .TimelineAnnotation timeline = 8;</code>
     */
    public java.util.List<? extends org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotationOrBuilder> 
        getTimelineOrBuilderList() {
      return timeline_;
    }
    /**
     * <code>repeated .TimelineAnnotation timeline = 8;</code>
     */
    public int getTimelineCount() {
      return timeline_.size();
    }
    /**
     * <code>repeated .TimelineAnnotation timeline = 8;</code>
     */
    public org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation getTimeline(int index) {
      return timeline_.get(index);
    }
    /**
     * <code>repeated .TimelineAnnotation timeline = 8;</code>
     */
    public org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotationOrBuilder getTimelineOrBuilder(
        int index) {
      return timeline_.get(index);
    }

    private void initFields() {
      traceId_ = 0L;
      parentId_ = 0L;
      start_ = 0L;
      stop_ = 0L;
      spanId_ = 0L;
      processId_ = "";
      description_ = "";
      timeline_ = java.util.Collections.emptyList();
    }
    private byte memoizedIsInitialized = -1;
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized != -1) return isInitialized == 1;

      if (!hasTraceId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasParentId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasStart()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasStop()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasSpanId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasProcessId()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasDescription()) {
        memoizedIsInitialized = 0;
        return false;
      }
      for (int i = 0; i < getTimelineCount(); i++) {
        if (!getTimeline(i).isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getSerializedSize();
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        output.writeInt64(1, traceId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        output.writeInt64(2, parentId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        output.writeInt64(3, start_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        output.writeInt64(4, stop_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        output.writeInt64(5, spanId_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        output.writeBytes(6, getProcessIdBytes());
      }
      if (((bitField0_ & 0x00000040) == 0x00000040)) {
        output.writeBytes(7, getDescriptionBytes());
      }
      for (int i = 0; i < timeline_.size(); i++) {
        output.writeMessage(8, timeline_.get(i));
      }
      getUnknownFields().writeTo(output);
    }

    private int memoizedSerializedSize = -1;
    public int getSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) == 0x00000001)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(1, traceId_);
      }
      if (((bitField0_ & 0x00000002) == 0x00000002)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(2, parentId_);
      }
      if (((bitField0_ & 0x00000004) == 0x00000004)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(3, start_);
      }
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(4, stop_);
      }
      if (((bitField0_ & 0x00000010) == 0x00000010)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt64Size(5, spanId_);
      }
      if (((bitField0_ & 0x00000020) == 0x00000020)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(6, getProcessIdBytes());
      }
      if (((bitField0_ & 0x00000040) == 0x00000040)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(7, getDescriptionBytes());
      }
      for (int i = 0; i < timeline_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(8, timeline_.get(i));
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSerializedSize = size;
      return size;
    }

    private static final long serialVersionUID = 0L;
    @java.lang.Override
    protected java.lang.Object writeReplace()
        throws java.io.ObjectStreamException {
      return super.writeReplace();
    }

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

      boolean result = true;
      result = result && (hasTraceId() == other.hasTraceId());
      if (hasTraceId()) {
        result = result && (getTraceId()
            == other.getTraceId());
      }
      result = result && (hasParentId() == other.hasParentId());
      if (hasParentId()) {
        result = result && (getParentId()
            == other.getParentId());
      }
      result = result && (hasStart() == other.hasStart());
      if (hasStart()) {
        result = result && (getStart()
            == other.getStart());
      }
      result = result && (hasStop() == other.hasStop());
      if (hasStop()) {
        result = result && (getStop()
            == other.getStop());
      }
      result = result && (hasSpanId() == other.hasSpanId());
      if (hasSpanId()) {
        result = result && (getSpanId()
            == other.getSpanId());
      }
      result = result && (hasProcessId() == other.hasProcessId());
      if (hasProcessId()) {
        result = result && getProcessId()
            .equals(other.getProcessId());
      }
      result = result && (hasDescription() == other.hasDescription());
      if (hasDescription()) {
        result = result && getDescription()
            .equals(other.getDescription());
      }
      result = result && getTimelineList()
          .equals(other.getTimelineList());
      result = result &&
          getUnknownFields().equals(other.getUnknownFields());
      return result;
    }

    private int memoizedHashCode = 0;
    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptorForType().hashCode();
      if (hasTraceId()) {
        hash = (37 * hash) + TRACE_ID_FIELD_NUMBER;
        hash = (53 * hash) + hashLong(getTraceId());
      }
      if (hasParentId()) {
        hash = (37 * hash) + PARENT_ID_FIELD_NUMBER;
        hash = (53 * hash) + hashLong(getParentId());
      }
      if (hasStart()) {
        hash = (37 * hash) + START_FIELD_NUMBER;
        hash = (53 * hash) + hashLong(getStart());
      }
      if (hasStop()) {
        hash = (37 * hash) + STOP_FIELD_NUMBER;
        hash = (53 * hash) + hashLong(getStop());
      }
      if (hasSpanId()) {
        hash = (37 * hash) + SPAN_ID_FIELD_NUMBER;
        hash = (53 * hash) + hashLong(getSpanId());
      }
      if (hasProcessId()) {
        hash = (37 * hash) + PROCESS_ID_FIELD_NUMBER;
        hash = (53 * hash) + getProcessId().hashCode();
      }
      if (hasDescription()) {
        hash = (37 * hash) + DESCRIPTION_FIELD_NUMBER;
        hash = (53 * hash) + getDescription().hashCode();
      }
      if (getTimelineCount() > 0) {
        hash = (37 * hash) + TIMELINE_FIELD_NUMBER;
        hash = (53 * hash) + getTimelineList().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.htrace.protobuf.generated.SpanProtos.Span parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.htrace.protobuf.generated.SpanProtos.Span 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.htrace.protobuf.generated.SpanProtos.Span parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.htrace.protobuf.generated.SpanProtos.Span parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.htrace.protobuf.generated.SpanProtos.Span parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.htrace.protobuf.generated.SpanProtos.Span parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }
    public static org.apache.htrace.protobuf.generated.SpanProtos.Span parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input);
    }
    public static org.apache.htrace.protobuf.generated.SpanProtos.Span parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseDelimitedFrom(input, extensionRegistry);
    }
    public static org.apache.htrace.protobuf.generated.SpanProtos.Span parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return PARSER.parseFrom(input);
    }
    public static org.apache.htrace.protobuf.generated.SpanProtos.Span parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return PARSER.parseFrom(input, extensionRegistry);
    }

    public static Builder newBuilder() { return Builder.create(); }
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder(org.apache.htrace.protobuf.generated.SpanProtos.Span prototype) {
      return newBuilder().mergeFrom(prototype);
    }
    public Builder toBuilder() { return newBuilder(this); }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code Span}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessage.Builder<Builder>
       implements org.apache.htrace.protobuf.generated.SpanProtos.SpanOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.htrace.protobuf.generated.SpanProtos.internal_static_Span_descriptor;
      }

      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.htrace.protobuf.generated.SpanProtos.internal_static_Span_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.htrace.protobuf.generated.SpanProtos.Span.class, org.apache.htrace.protobuf.generated.SpanProtos.Span.Builder.class);
      }

      // Construct using org.apache.htrace.protobuf.generated.SpanProtos.Span.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
          getTimelineFieldBuilder();
        }
      }
      private static Builder create() {
        return new Builder();
      }

      public Builder clear() {
        super.clear();
        traceId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000001);
        parentId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000002);
        start_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000004);
        stop_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000008);
        spanId_ = 0L;
        bitField0_ = (bitField0_ & ~0x00000010);
        processId_ = "";
        bitField0_ = (bitField0_ & ~0x00000020);
        description_ = "";
        bitField0_ = (bitField0_ & ~0x00000040);
        if (timelineBuilder_ == null) {
          timeline_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000080);
        } else {
          timelineBuilder_.clear();
        }
        return this;
      }

      public Builder clone() {
        return create().mergeFrom(buildPartial());
      }

      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.htrace.protobuf.generated.SpanProtos.internal_static_Span_descriptor;
      }

      public org.apache.htrace.protobuf.generated.SpanProtos.Span getDefaultInstanceForType() {
        return org.apache.htrace.protobuf.generated.SpanProtos.Span.getDefaultInstance();
      }

      public org.apache.htrace.protobuf.generated.SpanProtos.Span build() {
        org.apache.htrace.protobuf.generated.SpanProtos.Span result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      public org.apache.htrace.protobuf.generated.SpanProtos.Span buildPartial() {
        org.apache.htrace.protobuf.generated.SpanProtos.Span result = new org.apache.htrace.protobuf.generated.SpanProtos.Span(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
          to_bitField0_ |= 0x00000001;
        }
        result.traceId_ = traceId_;
        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
          to_bitField0_ |= 0x00000002;
        }
        result.parentId_ = parentId_;
        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
          to_bitField0_ |= 0x00000004;
        }
        result.start_ = start_;
        if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
          to_bitField0_ |= 0x00000008;
        }
        result.stop_ = stop_;
        if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
          to_bitField0_ |= 0x00000010;
        }
        result.spanId_ = spanId_;
        if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
          to_bitField0_ |= 0x00000020;
        }
        result.processId_ = processId_;
        if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
          to_bitField0_ |= 0x00000040;
        }
        result.description_ = description_;
        if (timelineBuilder_ == null) {
          if (((bitField0_ & 0x00000080) == 0x00000080)) {
            timeline_ = java.util.Collections.unmodifiableList(timeline_);
            bitField0_ = (bitField0_ & ~0x00000080);
          }
          result.timeline_ = timeline_;
        } else {
          result.timeline_ = timelineBuilder_.build();
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.htrace.protobuf.generated.SpanProtos.Span) {
          return mergeFrom((org.apache.htrace.protobuf.generated.SpanProtos.Span)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.htrace.protobuf.generated.SpanProtos.Span other) {
        if (other == org.apache.htrace.protobuf.generated.SpanProtos.Span.getDefaultInstance()) return this;
        if (other.hasTraceId()) {
          setTraceId(other.getTraceId());
        }
        if (other.hasParentId()) {
          setParentId(other.getParentId());
        }
        if (other.hasStart()) {
          setStart(other.getStart());
        }
        if (other.hasStop()) {
          setStop(other.getStop());
        }
        if (other.hasSpanId()) {
          setSpanId(other.getSpanId());
        }
        if (other.hasProcessId()) {
          bitField0_ |= 0x00000020;
          processId_ = other.processId_;
          onChanged();
        }
        if (other.hasDescription()) {
          bitField0_ |= 0x00000040;
          description_ = other.description_;
          onChanged();
        }
        if (timelineBuilder_ == null) {
          if (!other.timeline_.isEmpty()) {
            if (timeline_.isEmpty()) {
              timeline_ = other.timeline_;
              bitField0_ = (bitField0_ & ~0x00000080);
            } else {
              ensureTimelineIsMutable();
              timeline_.addAll(other.timeline_);
            }
            onChanged();
          }
        } else {
          if (!other.timeline_.isEmpty()) {
            if (timelineBuilder_.isEmpty()) {
              timelineBuilder_.dispose();
              timelineBuilder_ = null;
              timeline_ = other.timeline_;
              bitField0_ = (bitField0_ & ~0x00000080);
              timelineBuilder_ = 
                com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
                   getTimelineFieldBuilder() : null;
            } else {
              timelineBuilder_.addAllMessages(other.timeline_);
            }
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        return this;
      }

      public final boolean isInitialized() {
        if (!hasTraceId()) {
          
          return false;
        }
        if (!hasParentId()) {
          
          return false;
        }
        if (!hasStart()) {
          
          return false;
        }
        if (!hasStop()) {
          
          return false;
        }
        if (!hasSpanId()) {
          
          return false;
        }
        if (!hasProcessId()) {
          
          return false;
        }
        if (!hasDescription()) {
          
          return false;
        }
        for (int i = 0; i < getTimelineCount(); i++) {
          if (!getTimeline(i).isInitialized()) {
            
            return false;
          }
        }
        return true;
      }

      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        org.apache.htrace.protobuf.generated.SpanProtos.Span parsedMessage = null;
        try {
          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          parsedMessage = (org.apache.htrace.protobuf.generated.SpanProtos.Span) e.getUnfinishedMessage();
          throw e;
        } finally {
          if (parsedMessage != null) {
            mergeFrom(parsedMessage);
          }
        }
        return this;
      }
      private int bitField0_;

      // required int64 trace_id = 1;
      private long traceId_ ;
      /**
       * <code>required int64 trace_id = 1;</code>
       */
      public boolean hasTraceId() {
        return ((bitField0_ & 0x00000001) == 0x00000001);
      }
      /**
       * <code>required int64 trace_id = 1;</code>
       */
      public long getTraceId() {
        return traceId_;
      }
      /**
       * <code>required int64 trace_id = 1;</code>
       */
      public Builder setTraceId(long value) {
        bitField0_ |= 0x00000001;
        traceId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 trace_id = 1;</code>
       */
      public Builder clearTraceId() {
        bitField0_ = (bitField0_ & ~0x00000001);
        traceId_ = 0L;
        onChanged();
        return this;
      }

      // required int64 parent_id = 2;
      private long parentId_ ;
      /**
       * <code>required int64 parent_id = 2;</code>
       */
      public boolean hasParentId() {
        return ((bitField0_ & 0x00000002) == 0x00000002);
      }
      /**
       * <code>required int64 parent_id = 2;</code>
       */
      public long getParentId() {
        return parentId_;
      }
      /**
       * <code>required int64 parent_id = 2;</code>
       */
      public Builder setParentId(long value) {
        bitField0_ |= 0x00000002;
        parentId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 parent_id = 2;</code>
       */
      public Builder clearParentId() {
        bitField0_ = (bitField0_ & ~0x00000002);
        parentId_ = 0L;
        onChanged();
        return this;
      }

      // required int64 start = 3;
      private long start_ ;
      /**
       * <code>required int64 start = 3;</code>
       */
      public boolean hasStart() {
        return ((bitField0_ & 0x00000004) == 0x00000004);
      }
      /**
       * <code>required int64 start = 3;</code>
       */
      public long getStart() {
        return start_;
      }
      /**
       * <code>required int64 start = 3;</code>
       */
      public Builder setStart(long value) {
        bitField0_ |= 0x00000004;
        start_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 start = 3;</code>
       */
      public Builder clearStart() {
        bitField0_ = (bitField0_ & ~0x00000004);
        start_ = 0L;
        onChanged();
        return this;
      }

      // required int64 stop = 4;
      private long stop_ ;
      /**
       * <code>required int64 stop = 4;</code>
       */
      public boolean hasStop() {
        return ((bitField0_ & 0x00000008) == 0x00000008);
      }
      /**
       * <code>required int64 stop = 4;</code>
       */
      public long getStop() {
        return stop_;
      }
      /**
       * <code>required int64 stop = 4;</code>
       */
      public Builder setStop(long value) {
        bitField0_ |= 0x00000008;
        stop_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 stop = 4;</code>
       */
      public Builder clearStop() {
        bitField0_ = (bitField0_ & ~0x00000008);
        stop_ = 0L;
        onChanged();
        return this;
      }

      // required int64 span_id = 5;
      private long spanId_ ;
      /**
       * <code>required int64 span_id = 5;</code>
       */
      public boolean hasSpanId() {
        return ((bitField0_ & 0x00000010) == 0x00000010);
      }
      /**
       * <code>required int64 span_id = 5;</code>
       */
      public long getSpanId() {
        return spanId_;
      }
      /**
       * <code>required int64 span_id = 5;</code>
       */
      public Builder setSpanId(long value) {
        bitField0_ |= 0x00000010;
        spanId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required int64 span_id = 5;</code>
       */
      public Builder clearSpanId() {
        bitField0_ = (bitField0_ & ~0x00000010);
        spanId_ = 0L;
        onChanged();
        return this;
      }

      // required string process_id = 6;
      private java.lang.Object processId_ = "";
      /**
       * <code>required string process_id = 6;</code>
       */
      public boolean hasProcessId() {
        return ((bitField0_ & 0x00000020) == 0x00000020);
      }
      /**
       * <code>required string process_id = 6;</code>
       */
      public java.lang.String getProcessId() {
        java.lang.Object ref = processId_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          processId_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>required string process_id = 6;</code>
       */
      public com.google.protobuf.ByteString
          getProcessIdBytes() {
        java.lang.Object ref = processId_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          processId_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>required string process_id = 6;</code>
       */
      public Builder setProcessId(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000020;
        processId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required string process_id = 6;</code>
       */
      public Builder clearProcessId() {
        bitField0_ = (bitField0_ & ~0x00000020);
        processId_ = getDefaultInstance().getProcessId();
        onChanged();
        return this;
      }
      /**
       * <code>required string process_id = 6;</code>
       */
      public Builder setProcessIdBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000020;
        processId_ = value;
        onChanged();
        return this;
      }

      // required string description = 7;
      private java.lang.Object description_ = "";
      /**
       * <code>required string description = 7;</code>
       */
      public boolean hasDescription() {
        return ((bitField0_ & 0x00000040) == 0x00000040);
      }
      /**
       * <code>required string description = 7;</code>
       */
      public java.lang.String getDescription() {
        java.lang.Object ref = description_;
        if (!(ref instanceof java.lang.String)) {
          java.lang.String s = ((com.google.protobuf.ByteString) ref)
              .toStringUtf8();
          description_ = s;
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>required string description = 7;</code>
       */
      public com.google.protobuf.ByteString
          getDescriptionBytes() {
        java.lang.Object ref = description_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          description_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>required string description = 7;</code>
       */
      public Builder setDescription(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000040;
        description_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required string description = 7;</code>
       */
      public Builder clearDescription() {
        bitField0_ = (bitField0_ & ~0x00000040);
        description_ = getDefaultInstance().getDescription();
        onChanged();
        return this;
      }
      /**
       * <code>required string description = 7;</code>
       */
      public Builder setDescriptionBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000040;
        description_ = value;
        onChanged();
        return this;
      }

      // repeated .TimelineAnnotation timeline = 8;
      private java.util.List<org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation> timeline_ =
        java.util.Collections.emptyList();
      private void ensureTimelineIsMutable() {
        if (!((bitField0_ & 0x00000080) == 0x00000080)) {
          timeline_ = new java.util.ArrayList<org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation>(timeline_);
          bitField0_ |= 0x00000080;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilder<
          org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation, org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation.Builder, org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotationOrBuilder> timelineBuilder_;

      /**
       * <code>repeated .TimelineAnnotation timeline = 8;</code>
       */
      public java.util.List<org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation> getTimelineList() {
        if (timelineBuilder_ == null) {
          return java.util.Collections.unmodifiableList(timeline_);
        } else {
          return timelineBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .TimelineAnnotation timeline = 8;</code>
       */
      public int getTimelineCount() {
        if (timelineBuilder_ == null) {
          return timeline_.size();
        } else {
          return timelineBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .TimelineAnnotation timeline = 8;</code>
       */
      public org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation getTimeline(int index) {
        if (timelineBuilder_ == null) {
          return timeline_.get(index);
        } else {
          return timelineBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .TimelineAnnotation timeline = 8;</code>
       */
      public Builder setTimeline(
          int index, org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation value) {
        if (timelineBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureTimelineIsMutable();
          timeline_.set(index, value);
          onChanged();
        } else {
          timelineBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .TimelineAnnotation timeline = 8;</code>
       */
      public Builder setTimeline(
          int index, org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation.Builder builderForValue) {
        if (timelineBuilder_ == null) {
          ensureTimelineIsMutable();
          timeline_.set(index, builderForValue.build());
          onChanged();
        } else {
          timelineBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .TimelineAnnotation timeline = 8;</code>
       */
      public Builder addTimeline(org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation value) {
        if (timelineBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureTimelineIsMutable();
          timeline_.add(value);
          onChanged();
        } else {
          timelineBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .TimelineAnnotation timeline = 8;</code>
       */
      public Builder addTimeline(
          int index, org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation value) {
        if (timelineBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureTimelineIsMutable();
          timeline_.add(index, value);
          onChanged();
        } else {
          timelineBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .TimelineAnnotation timeline = 8;</code>
       */
      public Builder addTimeline(
          org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation.Builder builderForValue) {
        if (timelineBuilder_ == null) {
          ensureTimelineIsMutable();
          timeline_.add(builderForValue.build());
          onChanged();
        } else {
          timelineBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .TimelineAnnotation timeline = 8;</code>
       */
      public Builder addTimeline(
          int index, org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation.Builder builderForValue) {
        if (timelineBuilder_ == null) {
          ensureTimelineIsMutable();
          timeline_.add(index, builderForValue.build());
          onChanged();
        } else {
          timelineBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .TimelineAnnotation timeline = 8;</code>
       */
      public Builder addAllTimeline(
          java.lang.Iterable<? extends org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation> values) {
        if (timelineBuilder_ == null) {
          ensureTimelineIsMutable();
          super.addAll(values, timeline_);
          onChanged();
        } else {
          timelineBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .TimelineAnnotation timeline = 8;</code>
       */
      public Builder clearTimeline() {
        if (timelineBuilder_ == null) {
          timeline_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000080);
          onChanged();
        } else {
          timelineBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .TimelineAnnotation timeline = 8;</code>
       */
      public Builder removeTimeline(int index) {
        if (timelineBuilder_ == null) {
          ensureTimelineIsMutable();
          timeline_.remove(index);
          onChanged();
        } else {
          timelineBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .TimelineAnnotation timeline = 8;</code>
       */
      public org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation.Builder getTimelineBuilder(
          int index) {
        return getTimelineFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .TimelineAnnotation timeline = 8;</code>
       */
      public org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotationOrBuilder getTimelineOrBuilder(
          int index) {
        if (timelineBuilder_ == null) {
          return timeline_.get(index);  } else {
          return timelineBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .TimelineAnnotation timeline = 8;</code>
       */
      public java.util.List<? extends org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotationOrBuilder> 
           getTimelineOrBuilderList() {
        if (timelineBuilder_ != null) {
          return timelineBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(timeline_);
        }
      }
      /**
       * <code>repeated .TimelineAnnotation timeline = 8;</code>
       */
      public org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation.Builder addTimelineBuilder() {
        return getTimelineFieldBuilder().addBuilder(
            org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation.getDefaultInstance());
      }
      /**
       * <code>repeated .TimelineAnnotation timeline = 8;</code>
       */
      public org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation.Builder addTimelineBuilder(
          int index) {
        return getTimelineFieldBuilder().addBuilder(
            index, org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation.getDefaultInstance());
      }
      /**
       * <code>repeated .TimelineAnnotation timeline = 8;</code>
       */
      public java.util.List<org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation.Builder> 
           getTimelineBuilderList() {
        return getTimelineFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilder<
          org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation, org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation.Builder, org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotationOrBuilder> 
          getTimelineFieldBuilder() {
        if (timelineBuilder_ == null) {
          timelineBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
              org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation, org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotation.Builder, org.apache.htrace.protobuf.generated.SpanProtos.TimelineAnnotationOrBuilder>(
                  timeline_,
                  ((bitField0_ & 0x00000080) == 0x00000080),
                  getParentForChildren(),
                  isClean());
          timeline_ = null;
        }
        return timelineBuilder_;
      }

      // @@protoc_insertion_point(builder_scope:Span)
    }

    static {
      defaultInstance = new Span(true);
      defaultInstance.initFields();
    }

    // @@protoc_insertion_point(class_scope:Span)
  }

  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_TimelineAnnotation_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_TimelineAnnotation_fieldAccessorTable;
  private static com.google.protobuf.Descriptors.Descriptor
    internal_static_Span_descriptor;
  private static
    com.google.protobuf.GeneratedMessage.FieldAccessorTable
      internal_static_Span_fieldAccessorTable;

  public static com.google.protobuf.Descriptors.FileDescriptor
      getDescriptor() {
    return descriptor;
  }
  private static com.google.protobuf.Descriptors.FileDescriptor
      descriptor;
  static {
    java.lang.String[] descriptorData = {
      "\n\nSpan.proto\"3\n\022TimelineAnnotation\022\014\n\004ti" +
      "me\030\001 \002(\003\022\017\n\007message\030\002 \002(\t\"\251\001\n\004Span\022\020\n\010tr" +
      "ace_id\030\001 \002(\003\022\021\n\tparent_id\030\002 \002(\003\022\r\n\005start" +
      "\030\003 \002(\003\022\014\n\004stop\030\004 \002(\003\022\017\n\007span_id\030\005 \002(\003\022\022\n" +
      "\nprocess_id\030\006 \002(\t\022\023\n\013description\030\007 \002(\t\022%" +
      "\n\010timeline\030\010 \003(\0132\023.TimelineAnnotationB0\n" +
      "\035org.htrace.protobuf.generatedB\nSpanProt" +
      "osH\001\240\001\001"
    };
    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
        public com.google.protobuf.ExtensionRegistry assignDescriptors(
            com.google.protobuf.Descriptors.FileDescriptor root) {
          descriptor = root;
          internal_static_TimelineAnnotation_descriptor =
            getDescriptor().getMessageTypes().get(0);
          internal_static_TimelineAnnotation_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_TimelineAnnotation_descriptor,
              new java.lang.String[] { "Time", "Message", });
          internal_static_Span_descriptor =
            getDescriptor().getMessageTypes().get(1);
          internal_static_Span_fieldAccessorTable = new
            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
              internal_static_Span_descriptor,
              new java.lang.String[] { "TraceId", "ParentId", "Start", "Stop", "SpanId", "ProcessId", "Description", "Timeline", });
          return null;
        }
      };
    com.google.protobuf.Descriptors.FileDescriptor
      .internalBuildGeneratedFileFrom(descriptorData,
        new com.google.protobuf.Descriptors.FileDescriptor[] {
        }, assigner);
  }

  // @@protoc_insertion_point(outer_class_scope)
}
