// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: google/monitoring/v3/common.proto

package com.google.monitoring.v3;

/**
 * <pre>
 * Describes how to combine multiple time series to provide different views of
 * the data.  Aggregation consists of an alignment step on individual time
 * series (`alignment_period` and `per_series_aligner`) followed by an optional
 * reduction step of the data across the aligned time series
 * (`cross_series_reducer` and `group_by_fields`).  For more details, see
 * [Aggregation](/monitoring/api/learn_more#aggregation).
 * </pre>
 *
 * Protobuf type {@code google.monitoring.v3.Aggregation}
 */
public  final class Aggregation extends
    com.google.protobuf.GeneratedMessageV3 implements
    // @@protoc_insertion_point(message_implements:google.monitoring.v3.Aggregation)
    AggregationOrBuilder {
private static final long serialVersionUID = 0L;
  // Use Aggregation.newBuilder() to construct.
  private Aggregation(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
    super(builder);
  }
  private Aggregation() {
    perSeriesAligner_ = 0;
    crossSeriesReducer_ = 0;
    groupByFields_ = com.google.protobuf.LazyStringArrayList.EMPTY;
  }

  @java.lang.Override
  public final com.google.protobuf.UnknownFieldSet
  getUnknownFields() {
    return this.unknownFields;
  }
  private Aggregation(
      com.google.protobuf.CodedInputStream input,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws com.google.protobuf.InvalidProtocolBufferException {
    this();
    if (extensionRegistry == null) {
      throw new java.lang.NullPointerException();
    }
    int mutable_bitField0_ = 0;
    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
        com.google.protobuf.UnknownFieldSet.newBuilder();
    try {
      boolean done = false;
      while (!done) {
        int tag = input.readTag();
        switch (tag) {
          case 0:
            done = true;
            break;
          default: {
            if (!parseUnknownFieldProto3(
                input, unknownFields, extensionRegistry, tag)) {
              done = true;
            }
            break;
          }
          case 10: {
            com.google.protobuf.Duration.Builder subBuilder = null;
            if (alignmentPeriod_ != null) {
              subBuilder = alignmentPeriod_.toBuilder();
            }
            alignmentPeriod_ = input.readMessage(com.google.protobuf.Duration.parser(), extensionRegistry);
            if (subBuilder != null) {
              subBuilder.mergeFrom(alignmentPeriod_);
              alignmentPeriod_ = subBuilder.buildPartial();
            }

            break;
          }
          case 16: {
            int rawValue = input.readEnum();

            perSeriesAligner_ = rawValue;
            break;
          }
          case 32: {
            int rawValue = input.readEnum();

            crossSeriesReducer_ = rawValue;
            break;
          }
          case 42: {
            java.lang.String s = input.readStringRequireUtf8();
            if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
              groupByFields_ = new com.google.protobuf.LazyStringArrayList();
              mutable_bitField0_ |= 0x00000008;
            }
            groupByFields_.add(s);
            break;
          }
        }
      }
    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
      throw e.setUnfinishedMessage(this);
    } catch (java.io.IOException e) {
      throw new com.google.protobuf.InvalidProtocolBufferException(
          e).setUnfinishedMessage(this);
    } finally {
      if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
        groupByFields_ = groupByFields_.getUnmodifiableView();
      }
      this.unknownFields = unknownFields.build();
      makeExtensionsImmutable();
    }
  }
  public static final com.google.protobuf.Descriptors.Descriptor
      getDescriptor() {
    return com.google.monitoring.v3.CommonProto.internal_static_google_monitoring_v3_Aggregation_descriptor;
  }

  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internalGetFieldAccessorTable() {
    return com.google.monitoring.v3.CommonProto.internal_static_google_monitoring_v3_Aggregation_fieldAccessorTable
        .ensureFieldAccessorsInitialized(
            com.google.monitoring.v3.Aggregation.class, com.google.monitoring.v3.Aggregation.Builder.class);
  }

  /**
   * <pre>
   * The Aligner describes how to bring the data points in a single
   * time series into temporal alignment.
   * </pre>
   *
   * Protobuf enum {@code google.monitoring.v3.Aggregation.Aligner}
   */
  public enum Aligner
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <pre>
     * No alignment. Raw data is returned. Not valid if cross-time
     * series reduction is requested. The value type of the result is
     * the same as the value type of the input.
     * </pre>
     *
     * <code>ALIGN_NONE = 0;</code>
     */
    ALIGN_NONE(0),
    /**
     * <pre>
     * Align and convert to delta metric type. This alignment is valid
     * for cumulative metrics and delta metrics. Aligning an existing
     * delta metric to a delta metric requires that the alignment
     * period be increased. The value type of the result is the same
     * as the value type of the input.
     * One can think of this aligner as a rate but without time units; that
     * is, the output is conceptually (second_point - first_point).
     * </pre>
     *
     * <code>ALIGN_DELTA = 1;</code>
     */
    ALIGN_DELTA(1),
    /**
     * <pre>
     * Align and convert to a rate. This alignment is valid for
     * cumulative metrics and delta metrics with numeric values. The output is a
     * gauge metric with value type
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
     * One can think of this aligner as conceptually providing the slope of
     * the line that passes through the value at the start and end of the
     * window. In other words, this is conceptually ((y1 - y0)/(t1 - t0)),
     * and the output unit is one that has a "/time" dimension.
     * If, by rate, you are looking for percentage change, see the
     * `ALIGN_PERCENT_CHANGE` aligner option.
     * </pre>
     *
     * <code>ALIGN_RATE = 2;</code>
     */
    ALIGN_RATE(2),
    /**
     * <pre>
     * Align by interpolating between adjacent points around the
     * period boundary. This alignment is valid for gauge
     * metrics with numeric values. The value type of the result is the same
     * as the value type of the input.
     * </pre>
     *
     * <code>ALIGN_INTERPOLATE = 3;</code>
     */
    ALIGN_INTERPOLATE(3),
    /**
     * <pre>
     * Align by shifting the oldest data point before the period
     * boundary to the boundary. This alignment is valid for gauge
     * metrics. The value type of the result is the same as the
     * value type of the input.
     * </pre>
     *
     * <code>ALIGN_NEXT_OLDER = 4;</code>
     */
    ALIGN_NEXT_OLDER(4),
    /**
     * <pre>
     * Align time series via aggregation. The resulting data point in
     * the alignment period is the minimum of all data points in the
     * period. This alignment is valid for gauge and delta metrics with numeric
     * values. The value type of the result is the same as the value
     * type of the input.
     * </pre>
     *
     * <code>ALIGN_MIN = 10;</code>
     */
    ALIGN_MIN(10),
    /**
     * <pre>
     * Align time series via aggregation. The resulting data point in
     * the alignment period is the maximum of all data points in the
     * period. This alignment is valid for gauge and delta metrics with numeric
     * values. The value type of the result is the same as the value
     * type of the input.
     * </pre>
     *
     * <code>ALIGN_MAX = 11;</code>
     */
    ALIGN_MAX(11),
    /**
     * <pre>
     * Align time series via aggregation. The resulting data point in
     * the alignment period is the average or arithmetic mean of all
     * data points in the period. This alignment is valid for gauge and delta
     * metrics with numeric values. The value type of the output is
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
     * </pre>
     *
     * <code>ALIGN_MEAN = 12;</code>
     */
    ALIGN_MEAN(12),
    /**
     * <pre>
     * Align time series via aggregation. The resulting data point in
     * the alignment period is the count of all data points in the
     * period. This alignment is valid for gauge and delta metrics with numeric
     * or Boolean values. The value type of the output is
     * [INT64][google.api.MetricDescriptor.ValueType.INT64].
     * </pre>
     *
     * <code>ALIGN_COUNT = 13;</code>
     */
    ALIGN_COUNT(13),
    /**
     * <pre>
     * Align time series via aggregation. The resulting data point in
     * the alignment period is the sum of all data points in the
     * period. This alignment is valid for gauge and delta metrics with numeric
     * and distribution values. The value type of the output is the
     * same as the value type of the input.
     * </pre>
     *
     * <code>ALIGN_SUM = 14;</code>
     */
    ALIGN_SUM(14),
    /**
     * <pre>
     * Align time series via aggregation. The resulting data point in
     * the alignment period is the standard deviation of all data
     * points in the period. This alignment is valid for gauge and delta metrics
     * with numeric values. The value type of the output is
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
     * </pre>
     *
     * <code>ALIGN_STDDEV = 15;</code>
     */
    ALIGN_STDDEV(15),
    /**
     * <pre>
     * Align time series via aggregation. The resulting data point in
     * the alignment period is the count of True-valued data points in the
     * period. This alignment is valid for gauge metrics with
     * Boolean values. The value type of the output is
     * [INT64][google.api.MetricDescriptor.ValueType.INT64].
     * </pre>
     *
     * <code>ALIGN_COUNT_TRUE = 16;</code>
     */
    ALIGN_COUNT_TRUE(16),
    /**
     * <pre>
     * Align time series via aggregation. The resulting data point in
     * the alignment period is the count of False-valued data points in the
     * period. This alignment is valid for gauge metrics with
     * Boolean values. The value type of the output is
     * [INT64][google.api.MetricDescriptor.ValueType.INT64].
     * </pre>
     *
     * <code>ALIGN_COUNT_FALSE = 24;</code>
     */
    ALIGN_COUNT_FALSE(24),
    /**
     * <pre>
     * Align time series via aggregation. The resulting data point in
     * the alignment period is the fraction of True-valued data points in the
     * period. This alignment is valid for gauge metrics with Boolean values.
     * The output value is in the range [0, 1] and has value type
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
     * </pre>
     *
     * <code>ALIGN_FRACTION_TRUE = 17;</code>
     */
    ALIGN_FRACTION_TRUE(17),
    /**
     * <pre>
     * Align time series via aggregation. The resulting data point in
     * the alignment period is the 99th percentile of all data
     * points in the period. This alignment is valid for gauge and delta metrics
     * with distribution values. The output is a gauge metric with value type
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
     * </pre>
     *
     * <code>ALIGN_PERCENTILE_99 = 18;</code>
     */
    ALIGN_PERCENTILE_99(18),
    /**
     * <pre>
     * Align time series via aggregation. The resulting data point in
     * the alignment period is the 95th percentile of all data
     * points in the period. This alignment is valid for gauge and delta metrics
     * with distribution values. The output is a gauge metric with value type
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
     * </pre>
     *
     * <code>ALIGN_PERCENTILE_95 = 19;</code>
     */
    ALIGN_PERCENTILE_95(19),
    /**
     * <pre>
     * Align time series via aggregation. The resulting data point in
     * the alignment period is the 50th percentile of all data
     * points in the period. This alignment is valid for gauge and delta metrics
     * with distribution values. The output is a gauge metric with value type
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
     * </pre>
     *
     * <code>ALIGN_PERCENTILE_50 = 20;</code>
     */
    ALIGN_PERCENTILE_50(20),
    /**
     * <pre>
     * Align time series via aggregation. The resulting data point in
     * the alignment period is the 5th percentile of all data
     * points in the period. This alignment is valid for gauge and delta metrics
     * with distribution values. The output is a gauge metric with value type
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
     * </pre>
     *
     * <code>ALIGN_PERCENTILE_05 = 21;</code>
     */
    ALIGN_PERCENTILE_05(21),
    /**
     * <pre>
     * Align and convert to a percentage change. This alignment is valid for
     * gauge and delta metrics with numeric values. This alignment conceptually
     * computes the equivalent of "((current - previous)/previous)*100"
     * where previous value is determined based on the alignmentPeriod.
     * In the event that previous is 0 the calculated value is infinity with the
     * exception that if both (current - previous) and previous are 0 the
     * calculated value is 0.
     * A 10 minute moving mean is computed at each point of the time window
     * prior to the above calculation to smooth the metric and prevent false
     * positives from very short lived spikes.
     * Only applicable for data that is &gt;= 0. Any values &lt; 0 are treated as
     * no data. While delta metrics are accepted by this alignment special care
     * should be taken that the values for the metric will always be positive.
     * The output is a gauge metric with value type
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
     * </pre>
     *
     * <code>ALIGN_PERCENT_CHANGE = 23;</code>
     */
    ALIGN_PERCENT_CHANGE(23),
    UNRECOGNIZED(-1),
    ;

    /**
     * <pre>
     * No alignment. Raw data is returned. Not valid if cross-time
     * series reduction is requested. The value type of the result is
     * the same as the value type of the input.
     * </pre>
     *
     * <code>ALIGN_NONE = 0;</code>
     */
    public static final int ALIGN_NONE_VALUE = 0;
    /**
     * <pre>
     * Align and convert to delta metric type. This alignment is valid
     * for cumulative metrics and delta metrics. Aligning an existing
     * delta metric to a delta metric requires that the alignment
     * period be increased. The value type of the result is the same
     * as the value type of the input.
     * One can think of this aligner as a rate but without time units; that
     * is, the output is conceptually (second_point - first_point).
     * </pre>
     *
     * <code>ALIGN_DELTA = 1;</code>
     */
    public static final int ALIGN_DELTA_VALUE = 1;
    /**
     * <pre>
     * Align and convert to a rate. This alignment is valid for
     * cumulative metrics and delta metrics with numeric values. The output is a
     * gauge metric with value type
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
     * One can think of this aligner as conceptually providing the slope of
     * the line that passes through the value at the start and end of the
     * window. In other words, this is conceptually ((y1 - y0)/(t1 - t0)),
     * and the output unit is one that has a "/time" dimension.
     * If, by rate, you are looking for percentage change, see the
     * `ALIGN_PERCENT_CHANGE` aligner option.
     * </pre>
     *
     * <code>ALIGN_RATE = 2;</code>
     */
    public static final int ALIGN_RATE_VALUE = 2;
    /**
     * <pre>
     * Align by interpolating between adjacent points around the
     * period boundary. This alignment is valid for gauge
     * metrics with numeric values. The value type of the result is the same
     * as the value type of the input.
     * </pre>
     *
     * <code>ALIGN_INTERPOLATE = 3;</code>
     */
    public static final int ALIGN_INTERPOLATE_VALUE = 3;
    /**
     * <pre>
     * Align by shifting the oldest data point before the period
     * boundary to the boundary. This alignment is valid for gauge
     * metrics. The value type of the result is the same as the
     * value type of the input.
     * </pre>
     *
     * <code>ALIGN_NEXT_OLDER = 4;</code>
     */
    public static final int ALIGN_NEXT_OLDER_VALUE = 4;
    /**
     * <pre>
     * Align time series via aggregation. The resulting data point in
     * the alignment period is the minimum of all data points in the
     * period. This alignment is valid for gauge and delta metrics with numeric
     * values. The value type of the result is the same as the value
     * type of the input.
     * </pre>
     *
     * <code>ALIGN_MIN = 10;</code>
     */
    public static final int ALIGN_MIN_VALUE = 10;
    /**
     * <pre>
     * Align time series via aggregation. The resulting data point in
     * the alignment period is the maximum of all data points in the
     * period. This alignment is valid for gauge and delta metrics with numeric
     * values. The value type of the result is the same as the value
     * type of the input.
     * </pre>
     *
     * <code>ALIGN_MAX = 11;</code>
     */
    public static final int ALIGN_MAX_VALUE = 11;
    /**
     * <pre>
     * Align time series via aggregation. The resulting data point in
     * the alignment period is the average or arithmetic mean of all
     * data points in the period. This alignment is valid for gauge and delta
     * metrics with numeric values. The value type of the output is
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
     * </pre>
     *
     * <code>ALIGN_MEAN = 12;</code>
     */
    public static final int ALIGN_MEAN_VALUE = 12;
    /**
     * <pre>
     * Align time series via aggregation. The resulting data point in
     * the alignment period is the count of all data points in the
     * period. This alignment is valid for gauge and delta metrics with numeric
     * or Boolean values. The value type of the output is
     * [INT64][google.api.MetricDescriptor.ValueType.INT64].
     * </pre>
     *
     * <code>ALIGN_COUNT = 13;</code>
     */
    public static final int ALIGN_COUNT_VALUE = 13;
    /**
     * <pre>
     * Align time series via aggregation. The resulting data point in
     * the alignment period is the sum of all data points in the
     * period. This alignment is valid for gauge and delta metrics with numeric
     * and distribution values. The value type of the output is the
     * same as the value type of the input.
     * </pre>
     *
     * <code>ALIGN_SUM = 14;</code>
     */
    public static final int ALIGN_SUM_VALUE = 14;
    /**
     * <pre>
     * Align time series via aggregation. The resulting data point in
     * the alignment period is the standard deviation of all data
     * points in the period. This alignment is valid for gauge and delta metrics
     * with numeric values. The value type of the output is
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
     * </pre>
     *
     * <code>ALIGN_STDDEV = 15;</code>
     */
    public static final int ALIGN_STDDEV_VALUE = 15;
    /**
     * <pre>
     * Align time series via aggregation. The resulting data point in
     * the alignment period is the count of True-valued data points in the
     * period. This alignment is valid for gauge metrics with
     * Boolean values. The value type of the output is
     * [INT64][google.api.MetricDescriptor.ValueType.INT64].
     * </pre>
     *
     * <code>ALIGN_COUNT_TRUE = 16;</code>
     */
    public static final int ALIGN_COUNT_TRUE_VALUE = 16;
    /**
     * <pre>
     * Align time series via aggregation. The resulting data point in
     * the alignment period is the count of False-valued data points in the
     * period. This alignment is valid for gauge metrics with
     * Boolean values. The value type of the output is
     * [INT64][google.api.MetricDescriptor.ValueType.INT64].
     * </pre>
     *
     * <code>ALIGN_COUNT_FALSE = 24;</code>
     */
    public static final int ALIGN_COUNT_FALSE_VALUE = 24;
    /**
     * <pre>
     * Align time series via aggregation. The resulting data point in
     * the alignment period is the fraction of True-valued data points in the
     * period. This alignment is valid for gauge metrics with Boolean values.
     * The output value is in the range [0, 1] and has value type
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
     * </pre>
     *
     * <code>ALIGN_FRACTION_TRUE = 17;</code>
     */
    public static final int ALIGN_FRACTION_TRUE_VALUE = 17;
    /**
     * <pre>
     * Align time series via aggregation. The resulting data point in
     * the alignment period is the 99th percentile of all data
     * points in the period. This alignment is valid for gauge and delta metrics
     * with distribution values. The output is a gauge metric with value type
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
     * </pre>
     *
     * <code>ALIGN_PERCENTILE_99 = 18;</code>
     */
    public static final int ALIGN_PERCENTILE_99_VALUE = 18;
    /**
     * <pre>
     * Align time series via aggregation. The resulting data point in
     * the alignment period is the 95th percentile of all data
     * points in the period. This alignment is valid for gauge and delta metrics
     * with distribution values. The output is a gauge metric with value type
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
     * </pre>
     *
     * <code>ALIGN_PERCENTILE_95 = 19;</code>
     */
    public static final int ALIGN_PERCENTILE_95_VALUE = 19;
    /**
     * <pre>
     * Align time series via aggregation. The resulting data point in
     * the alignment period is the 50th percentile of all data
     * points in the period. This alignment is valid for gauge and delta metrics
     * with distribution values. The output is a gauge metric with value type
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
     * </pre>
     *
     * <code>ALIGN_PERCENTILE_50 = 20;</code>
     */
    public static final int ALIGN_PERCENTILE_50_VALUE = 20;
    /**
     * <pre>
     * Align time series via aggregation. The resulting data point in
     * the alignment period is the 5th percentile of all data
     * points in the period. This alignment is valid for gauge and delta metrics
     * with distribution values. The output is a gauge metric with value type
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
     * </pre>
     *
     * <code>ALIGN_PERCENTILE_05 = 21;</code>
     */
    public static final int ALIGN_PERCENTILE_05_VALUE = 21;
    /**
     * <pre>
     * Align and convert to a percentage change. This alignment is valid for
     * gauge and delta metrics with numeric values. This alignment conceptually
     * computes the equivalent of "((current - previous)/previous)*100"
     * where previous value is determined based on the alignmentPeriod.
     * In the event that previous is 0 the calculated value is infinity with the
     * exception that if both (current - previous) and previous are 0 the
     * calculated value is 0.
     * A 10 minute moving mean is computed at each point of the time window
     * prior to the above calculation to smooth the metric and prevent false
     * positives from very short lived spikes.
     * Only applicable for data that is &gt;= 0. Any values &lt; 0 are treated as
     * no data. While delta metrics are accepted by this alignment special care
     * should be taken that the values for the metric will always be positive.
     * The output is a gauge metric with value type
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
     * </pre>
     *
     * <code>ALIGN_PERCENT_CHANGE = 23;</code>
     */
    public static final int ALIGN_PERCENT_CHANGE_VALUE = 23;


    public final int getNumber() {
      if (this == UNRECOGNIZED) {
        throw new java.lang.IllegalArgumentException(
            "Can't get the number of an unknown enum value.");
      }
      return value;
    }

    /**
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static Aligner valueOf(int value) {
      return forNumber(value);
    }

    public static Aligner forNumber(int value) {
      switch (value) {
        case 0: return ALIGN_NONE;
        case 1: return ALIGN_DELTA;
        case 2: return ALIGN_RATE;
        case 3: return ALIGN_INTERPOLATE;
        case 4: return ALIGN_NEXT_OLDER;
        case 10: return ALIGN_MIN;
        case 11: return ALIGN_MAX;
        case 12: return ALIGN_MEAN;
        case 13: return ALIGN_COUNT;
        case 14: return ALIGN_SUM;
        case 15: return ALIGN_STDDEV;
        case 16: return ALIGN_COUNT_TRUE;
        case 24: return ALIGN_COUNT_FALSE;
        case 17: return ALIGN_FRACTION_TRUE;
        case 18: return ALIGN_PERCENTILE_99;
        case 19: return ALIGN_PERCENTILE_95;
        case 20: return ALIGN_PERCENTILE_50;
        case 21: return ALIGN_PERCENTILE_05;
        case 23: return ALIGN_PERCENT_CHANGE;
        default: return null;
      }
    }

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

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return com.google.monitoring.v3.Aggregation.getDescriptor().getEnumTypes().get(0);
    }

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

    public static Aligner valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      if (desc.getIndex() == -1) {
        return UNRECOGNIZED;
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private Aligner(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:google.monitoring.v3.Aggregation.Aligner)
  }

  /**
   * <pre>
   * A Reducer describes how to aggregate data points from multiple
   * time series into a single time series.
   * </pre>
   *
   * Protobuf enum {@code google.monitoring.v3.Aggregation.Reducer}
   */
  public enum Reducer
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <pre>
     * No cross-time series reduction. The output of the aligner is
     * returned.
     * </pre>
     *
     * <code>REDUCE_NONE = 0;</code>
     */
    REDUCE_NONE(0),
    /**
     * <pre>
     * Reduce by computing the mean across time series for each
     * alignment period. This reducer is valid for delta and
     * gauge metrics with numeric or distribution values. The value type of the
     * output is [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
     * </pre>
     *
     * <code>REDUCE_MEAN = 1;</code>
     */
    REDUCE_MEAN(1),
    /**
     * <pre>
     * Reduce by computing the minimum across time series for each
     * alignment period. This reducer is valid for delta and
     * gauge metrics with numeric values. The value type of the output
     * is the same as the value type of the input.
     * </pre>
     *
     * <code>REDUCE_MIN = 2;</code>
     */
    REDUCE_MIN(2),
    /**
     * <pre>
     * Reduce by computing the maximum across time series for each
     * alignment period. This reducer is valid for delta and
     * gauge metrics with numeric values. The value type of the output
     * is the same as the value type of the input.
     * </pre>
     *
     * <code>REDUCE_MAX = 3;</code>
     */
    REDUCE_MAX(3),
    /**
     * <pre>
     * Reduce by computing the sum across time series for each
     * alignment period. This reducer is valid for delta and
     * gauge metrics with numeric and distribution values. The value type of
     * the output is the same as the value type of the input.
     * </pre>
     *
     * <code>REDUCE_SUM = 4;</code>
     */
    REDUCE_SUM(4),
    /**
     * <pre>
     * Reduce by computing the standard deviation across time series
     * for each alignment period. This reducer is valid for delta
     * and gauge metrics with numeric or distribution values. The value type of
     * the output is [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
     * </pre>
     *
     * <code>REDUCE_STDDEV = 5;</code>
     */
    REDUCE_STDDEV(5),
    /**
     * <pre>
     * Reduce by computing the count of data points across time series
     * for each alignment period. This reducer is valid for delta
     * and gauge metrics of numeric, Boolean, distribution, and string value
     * type. The value type of the output is
     * [INT64][google.api.MetricDescriptor.ValueType.INT64].
     * </pre>
     *
     * <code>REDUCE_COUNT = 6;</code>
     */
    REDUCE_COUNT(6),
    /**
     * <pre>
     * Reduce by computing the count of True-valued data points across time
     * series for each alignment period. This reducer is valid for delta
     * and gauge metrics of Boolean value type. The value type of
     * the output is [INT64][google.api.MetricDescriptor.ValueType.INT64].
     * </pre>
     *
     * <code>REDUCE_COUNT_TRUE = 7;</code>
     */
    REDUCE_COUNT_TRUE(7),
    /**
     * <pre>
     * Reduce by computing the count of False-valued data points across time
     * series for each alignment period. This reducer is valid for delta
     * and gauge metrics of Boolean value type. The value type of
     * the output is [INT64][google.api.MetricDescriptor.ValueType.INT64].
     * </pre>
     *
     * <code>REDUCE_COUNT_FALSE = 15;</code>
     */
    REDUCE_COUNT_FALSE(15),
    /**
     * <pre>
     * Reduce by computing the fraction of True-valued data points across time
     * series for each alignment period. This reducer is valid for delta
     * and gauge metrics of Boolean value type. The output value is in the
     * range [0, 1] and has value type
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
     * </pre>
     *
     * <code>REDUCE_FRACTION_TRUE = 8;</code>
     */
    REDUCE_FRACTION_TRUE(8),
    /**
     * <pre>
     * Reduce by computing 99th percentile of data points across time series
     * for each alignment period. This reducer is valid for gauge and delta
     * metrics of numeric and distribution type. The value of the output is
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE]
     * </pre>
     *
     * <code>REDUCE_PERCENTILE_99 = 9;</code>
     */
    REDUCE_PERCENTILE_99(9),
    /**
     * <pre>
     * Reduce by computing 95th percentile of data points across time series
     * for each alignment period. This reducer is valid for gauge and delta
     * metrics of numeric and distribution type. The value of the output is
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE]
     * </pre>
     *
     * <code>REDUCE_PERCENTILE_95 = 10;</code>
     */
    REDUCE_PERCENTILE_95(10),
    /**
     * <pre>
     * Reduce by computing 50th percentile of data points across time series
     * for each alignment period. This reducer is valid for gauge and delta
     * metrics of numeric and distribution type. The value of the output is
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE]
     * </pre>
     *
     * <code>REDUCE_PERCENTILE_50 = 11;</code>
     */
    REDUCE_PERCENTILE_50(11),
    /**
     * <pre>
     * Reduce by computing 5th percentile of data points across time series
     * for each alignment period. This reducer is valid for gauge and delta
     * metrics of numeric and distribution type. The value of the output is
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE]
     * </pre>
     *
     * <code>REDUCE_PERCENTILE_05 = 12;</code>
     */
    REDUCE_PERCENTILE_05(12),
    UNRECOGNIZED(-1),
    ;

    /**
     * <pre>
     * No cross-time series reduction. The output of the aligner is
     * returned.
     * </pre>
     *
     * <code>REDUCE_NONE = 0;</code>
     */
    public static final int REDUCE_NONE_VALUE = 0;
    /**
     * <pre>
     * Reduce by computing the mean across time series for each
     * alignment period. This reducer is valid for delta and
     * gauge metrics with numeric or distribution values. The value type of the
     * output is [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
     * </pre>
     *
     * <code>REDUCE_MEAN = 1;</code>
     */
    public static final int REDUCE_MEAN_VALUE = 1;
    /**
     * <pre>
     * Reduce by computing the minimum across time series for each
     * alignment period. This reducer is valid for delta and
     * gauge metrics with numeric values. The value type of the output
     * is the same as the value type of the input.
     * </pre>
     *
     * <code>REDUCE_MIN = 2;</code>
     */
    public static final int REDUCE_MIN_VALUE = 2;
    /**
     * <pre>
     * Reduce by computing the maximum across time series for each
     * alignment period. This reducer is valid for delta and
     * gauge metrics with numeric values. The value type of the output
     * is the same as the value type of the input.
     * </pre>
     *
     * <code>REDUCE_MAX = 3;</code>
     */
    public static final int REDUCE_MAX_VALUE = 3;
    /**
     * <pre>
     * Reduce by computing the sum across time series for each
     * alignment period. This reducer is valid for delta and
     * gauge metrics with numeric and distribution values. The value type of
     * the output is the same as the value type of the input.
     * </pre>
     *
     * <code>REDUCE_SUM = 4;</code>
     */
    public static final int REDUCE_SUM_VALUE = 4;
    /**
     * <pre>
     * Reduce by computing the standard deviation across time series
     * for each alignment period. This reducer is valid for delta
     * and gauge metrics with numeric or distribution values. The value type of
     * the output is [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
     * </pre>
     *
     * <code>REDUCE_STDDEV = 5;</code>
     */
    public static final int REDUCE_STDDEV_VALUE = 5;
    /**
     * <pre>
     * Reduce by computing the count of data points across time series
     * for each alignment period. This reducer is valid for delta
     * and gauge metrics of numeric, Boolean, distribution, and string value
     * type. The value type of the output is
     * [INT64][google.api.MetricDescriptor.ValueType.INT64].
     * </pre>
     *
     * <code>REDUCE_COUNT = 6;</code>
     */
    public static final int REDUCE_COUNT_VALUE = 6;
    /**
     * <pre>
     * Reduce by computing the count of True-valued data points across time
     * series for each alignment period. This reducer is valid for delta
     * and gauge metrics of Boolean value type. The value type of
     * the output is [INT64][google.api.MetricDescriptor.ValueType.INT64].
     * </pre>
     *
     * <code>REDUCE_COUNT_TRUE = 7;</code>
     */
    public static final int REDUCE_COUNT_TRUE_VALUE = 7;
    /**
     * <pre>
     * Reduce by computing the count of False-valued data points across time
     * series for each alignment period. This reducer is valid for delta
     * and gauge metrics of Boolean value type. The value type of
     * the output is [INT64][google.api.MetricDescriptor.ValueType.INT64].
     * </pre>
     *
     * <code>REDUCE_COUNT_FALSE = 15;</code>
     */
    public static final int REDUCE_COUNT_FALSE_VALUE = 15;
    /**
     * <pre>
     * Reduce by computing the fraction of True-valued data points across time
     * series for each alignment period. This reducer is valid for delta
     * and gauge metrics of Boolean value type. The output value is in the
     * range [0, 1] and has value type
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE].
     * </pre>
     *
     * <code>REDUCE_FRACTION_TRUE = 8;</code>
     */
    public static final int REDUCE_FRACTION_TRUE_VALUE = 8;
    /**
     * <pre>
     * Reduce by computing 99th percentile of data points across time series
     * for each alignment period. This reducer is valid for gauge and delta
     * metrics of numeric and distribution type. The value of the output is
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE]
     * </pre>
     *
     * <code>REDUCE_PERCENTILE_99 = 9;</code>
     */
    public static final int REDUCE_PERCENTILE_99_VALUE = 9;
    /**
     * <pre>
     * Reduce by computing 95th percentile of data points across time series
     * for each alignment period. This reducer is valid for gauge and delta
     * metrics of numeric and distribution type. The value of the output is
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE]
     * </pre>
     *
     * <code>REDUCE_PERCENTILE_95 = 10;</code>
     */
    public static final int REDUCE_PERCENTILE_95_VALUE = 10;
    /**
     * <pre>
     * Reduce by computing 50th percentile of data points across time series
     * for each alignment period. This reducer is valid for gauge and delta
     * metrics of numeric and distribution type. The value of the output is
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE]
     * </pre>
     *
     * <code>REDUCE_PERCENTILE_50 = 11;</code>
     */
    public static final int REDUCE_PERCENTILE_50_VALUE = 11;
    /**
     * <pre>
     * Reduce by computing 5th percentile of data points across time series
     * for each alignment period. This reducer is valid for gauge and delta
     * metrics of numeric and distribution type. The value of the output is
     * [DOUBLE][google.api.MetricDescriptor.ValueType.DOUBLE]
     * </pre>
     *
     * <code>REDUCE_PERCENTILE_05 = 12;</code>
     */
    public static final int REDUCE_PERCENTILE_05_VALUE = 12;


    public final int getNumber() {
      if (this == UNRECOGNIZED) {
        throw new java.lang.IllegalArgumentException(
            "Can't get the number of an unknown enum value.");
      }
      return value;
    }

    /**
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static Reducer valueOf(int value) {
      return forNumber(value);
    }

    public static Reducer forNumber(int value) {
      switch (value) {
        case 0: return REDUCE_NONE;
        case 1: return REDUCE_MEAN;
        case 2: return REDUCE_MIN;
        case 3: return REDUCE_MAX;
        case 4: return REDUCE_SUM;
        case 5: return REDUCE_STDDEV;
        case 6: return REDUCE_COUNT;
        case 7: return REDUCE_COUNT_TRUE;
        case 15: return REDUCE_COUNT_FALSE;
        case 8: return REDUCE_FRACTION_TRUE;
        case 9: return REDUCE_PERCENTILE_99;
        case 10: return REDUCE_PERCENTILE_95;
        case 11: return REDUCE_PERCENTILE_50;
        case 12: return REDUCE_PERCENTILE_05;
        default: return null;
      }
    }

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

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return com.google.monitoring.v3.Aggregation.getDescriptor().getEnumTypes().get(1);
    }

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

    public static Reducer valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      if (desc.getIndex() == -1) {
        return UNRECOGNIZED;
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private Reducer(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:google.monitoring.v3.Aggregation.Reducer)
  }

  private int bitField0_;
  public static final int ALIGNMENT_PERIOD_FIELD_NUMBER = 1;
  private com.google.protobuf.Duration alignmentPeriod_;
  /**
   * <pre>
   * The alignment period for per-[time series][google.monitoring.v3.TimeSeries]
   * alignment. If present, `alignmentPeriod` must be at least 60
   * seconds.  After per-time series alignment, each time series will
   * contain data points only on the period boundaries. If
   * `perSeriesAligner` is not specified or equals `ALIGN_NONE`, then
   * this field is ignored. If `perSeriesAligner` is specified and
   * does not equal `ALIGN_NONE`, then this field must be defined;
   * otherwise an error is returned.
   * </pre>
   *
   * <code>.google.protobuf.Duration alignment_period = 1;</code>
   */
  public boolean hasAlignmentPeriod() {
    return alignmentPeriod_ != null;
  }
  /**
   * <pre>
   * The alignment period for per-[time series][google.monitoring.v3.TimeSeries]
   * alignment. If present, `alignmentPeriod` must be at least 60
   * seconds.  After per-time series alignment, each time series will
   * contain data points only on the period boundaries. If
   * `perSeriesAligner` is not specified or equals `ALIGN_NONE`, then
   * this field is ignored. If `perSeriesAligner` is specified and
   * does not equal `ALIGN_NONE`, then this field must be defined;
   * otherwise an error is returned.
   * </pre>
   *
   * <code>.google.protobuf.Duration alignment_period = 1;</code>
   */
  public com.google.protobuf.Duration getAlignmentPeriod() {
    return alignmentPeriod_ == null ? com.google.protobuf.Duration.getDefaultInstance() : alignmentPeriod_;
  }
  /**
   * <pre>
   * The alignment period for per-[time series][google.monitoring.v3.TimeSeries]
   * alignment. If present, `alignmentPeriod` must be at least 60
   * seconds.  After per-time series alignment, each time series will
   * contain data points only on the period boundaries. If
   * `perSeriesAligner` is not specified or equals `ALIGN_NONE`, then
   * this field is ignored. If `perSeriesAligner` is specified and
   * does not equal `ALIGN_NONE`, then this field must be defined;
   * otherwise an error is returned.
   * </pre>
   *
   * <code>.google.protobuf.Duration alignment_period = 1;</code>
   */
  public com.google.protobuf.DurationOrBuilder getAlignmentPeriodOrBuilder() {
    return getAlignmentPeriod();
  }

  public static final int PER_SERIES_ALIGNER_FIELD_NUMBER = 2;
  private int perSeriesAligner_;
  /**
   * <pre>
   * The approach to be used to align individual time series. Not all
   * alignment functions may be applied to all time series, depending
   * on the metric type and value type of the original time
   * series. Alignment may change the metric type or the value type of
   * the time series.
   * Time series data must be aligned in order to perform cross-time
   * series reduction. If `crossSeriesReducer` is specified, then
   * `perSeriesAligner` must be specified and not equal `ALIGN_NONE`
   * and `alignmentPeriod` must be specified; otherwise, an error is
   * returned.
   * </pre>
   *
   * <code>.google.monitoring.v3.Aggregation.Aligner per_series_aligner = 2;</code>
   */
  public int getPerSeriesAlignerValue() {
    return perSeriesAligner_;
  }
  /**
   * <pre>
   * The approach to be used to align individual time series. Not all
   * alignment functions may be applied to all time series, depending
   * on the metric type and value type of the original time
   * series. Alignment may change the metric type or the value type of
   * the time series.
   * Time series data must be aligned in order to perform cross-time
   * series reduction. If `crossSeriesReducer` is specified, then
   * `perSeriesAligner` must be specified and not equal `ALIGN_NONE`
   * and `alignmentPeriod` must be specified; otherwise, an error is
   * returned.
   * </pre>
   *
   * <code>.google.monitoring.v3.Aggregation.Aligner per_series_aligner = 2;</code>
   */
  public com.google.monitoring.v3.Aggregation.Aligner getPerSeriesAligner() {
    com.google.monitoring.v3.Aggregation.Aligner result = com.google.monitoring.v3.Aggregation.Aligner.valueOf(perSeriesAligner_);
    return result == null ? com.google.monitoring.v3.Aggregation.Aligner.UNRECOGNIZED : result;
  }

  public static final int CROSS_SERIES_REDUCER_FIELD_NUMBER = 4;
  private int crossSeriesReducer_;
  /**
   * <pre>
   * The approach to be used to combine time series. Not all reducer
   * functions may be applied to all time series, depending on the
   * metric type and the value type of the original time
   * series. Reduction may change the metric type of value type of the
   * time series.
   * Time series data must be aligned in order to perform cross-time
   * series reduction. If `crossSeriesReducer` is specified, then
   * `perSeriesAligner` must be specified and not equal `ALIGN_NONE`
   * and `alignmentPeriod` must be specified; otherwise, an error is
   * returned.
   * </pre>
   *
   * <code>.google.monitoring.v3.Aggregation.Reducer cross_series_reducer = 4;</code>
   */
  public int getCrossSeriesReducerValue() {
    return crossSeriesReducer_;
  }
  /**
   * <pre>
   * The approach to be used to combine time series. Not all reducer
   * functions may be applied to all time series, depending on the
   * metric type and the value type of the original time
   * series. Reduction may change the metric type of value type of the
   * time series.
   * Time series data must be aligned in order to perform cross-time
   * series reduction. If `crossSeriesReducer` is specified, then
   * `perSeriesAligner` must be specified and not equal `ALIGN_NONE`
   * and `alignmentPeriod` must be specified; otherwise, an error is
   * returned.
   * </pre>
   *
   * <code>.google.monitoring.v3.Aggregation.Reducer cross_series_reducer = 4;</code>
   */
  public com.google.monitoring.v3.Aggregation.Reducer getCrossSeriesReducer() {
    com.google.monitoring.v3.Aggregation.Reducer result = com.google.monitoring.v3.Aggregation.Reducer.valueOf(crossSeriesReducer_);
    return result == null ? com.google.monitoring.v3.Aggregation.Reducer.UNRECOGNIZED : result;
  }

  public static final int GROUP_BY_FIELDS_FIELD_NUMBER = 5;
  private com.google.protobuf.LazyStringList groupByFields_;
  /**
   * <pre>
   * The set of fields to preserve when `crossSeriesReducer` is
   * specified. The `groupByFields` determine how the time series are
   * partitioned into subsets prior to applying the aggregation
   * function. Each subset contains time series that have the same
   * value for each of the grouping fields. Each individual time
   * series is a member of exactly one subset. The
   * `crossSeriesReducer` is applied to each subset of time series.
   * It is not possible to reduce across different resource types, so
   * this field implicitly contains `resource.type`.  Fields not
   * specified in `groupByFields` are aggregated away.  If
   * `groupByFields` is not specified and all the time series have
   * the same resource type, then the time series are aggregated into
   * a single output time series. If `crossSeriesReducer` is not
   * defined, this field is ignored.
   * </pre>
   *
   * <code>repeated string group_by_fields = 5;</code>
   */
  public com.google.protobuf.ProtocolStringList
      getGroupByFieldsList() {
    return groupByFields_;
  }
  /**
   * <pre>
   * The set of fields to preserve when `crossSeriesReducer` is
   * specified. The `groupByFields` determine how the time series are
   * partitioned into subsets prior to applying the aggregation
   * function. Each subset contains time series that have the same
   * value for each of the grouping fields. Each individual time
   * series is a member of exactly one subset. The
   * `crossSeriesReducer` is applied to each subset of time series.
   * It is not possible to reduce across different resource types, so
   * this field implicitly contains `resource.type`.  Fields not
   * specified in `groupByFields` are aggregated away.  If
   * `groupByFields` is not specified and all the time series have
   * the same resource type, then the time series are aggregated into
   * a single output time series. If `crossSeriesReducer` is not
   * defined, this field is ignored.
   * </pre>
   *
   * <code>repeated string group_by_fields = 5;</code>
   */
  public int getGroupByFieldsCount() {
    return groupByFields_.size();
  }
  /**
   * <pre>
   * The set of fields to preserve when `crossSeriesReducer` is
   * specified. The `groupByFields` determine how the time series are
   * partitioned into subsets prior to applying the aggregation
   * function. Each subset contains time series that have the same
   * value for each of the grouping fields. Each individual time
   * series is a member of exactly one subset. The
   * `crossSeriesReducer` is applied to each subset of time series.
   * It is not possible to reduce across different resource types, so
   * this field implicitly contains `resource.type`.  Fields not
   * specified in `groupByFields` are aggregated away.  If
   * `groupByFields` is not specified and all the time series have
   * the same resource type, then the time series are aggregated into
   * a single output time series. If `crossSeriesReducer` is not
   * defined, this field is ignored.
   * </pre>
   *
   * <code>repeated string group_by_fields = 5;</code>
   */
  public java.lang.String getGroupByFields(int index) {
    return groupByFields_.get(index);
  }
  /**
   * <pre>
   * The set of fields to preserve when `crossSeriesReducer` is
   * specified. The `groupByFields` determine how the time series are
   * partitioned into subsets prior to applying the aggregation
   * function. Each subset contains time series that have the same
   * value for each of the grouping fields. Each individual time
   * series is a member of exactly one subset. The
   * `crossSeriesReducer` is applied to each subset of time series.
   * It is not possible to reduce across different resource types, so
   * this field implicitly contains `resource.type`.  Fields not
   * specified in `groupByFields` are aggregated away.  If
   * `groupByFields` is not specified and all the time series have
   * the same resource type, then the time series are aggregated into
   * a single output time series. If `crossSeriesReducer` is not
   * defined, this field is ignored.
   * </pre>
   *
   * <code>repeated string group_by_fields = 5;</code>
   */
  public com.google.protobuf.ByteString
      getGroupByFieldsBytes(int index) {
    return groupByFields_.getByteString(index);
  }

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

    memoizedIsInitialized = 1;
    return true;
  }

  public void writeTo(com.google.protobuf.CodedOutputStream output)
                      throws java.io.IOException {
    if (alignmentPeriod_ != null) {
      output.writeMessage(1, getAlignmentPeriod());
    }
    if (perSeriesAligner_ != com.google.monitoring.v3.Aggregation.Aligner.ALIGN_NONE.getNumber()) {
      output.writeEnum(2, perSeriesAligner_);
    }
    if (crossSeriesReducer_ != com.google.monitoring.v3.Aggregation.Reducer.REDUCE_NONE.getNumber()) {
      output.writeEnum(4, crossSeriesReducer_);
    }
    for (int i = 0; i < groupByFields_.size(); i++) {
      com.google.protobuf.GeneratedMessageV3.writeString(output, 5, groupByFields_.getRaw(i));
    }
    unknownFields.writeTo(output);
  }

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

    size = 0;
    if (alignmentPeriod_ != null) {
      size += com.google.protobuf.CodedOutputStream
        .computeMessageSize(1, getAlignmentPeriod());
    }
    if (perSeriesAligner_ != com.google.monitoring.v3.Aggregation.Aligner.ALIGN_NONE.getNumber()) {
      size += com.google.protobuf.CodedOutputStream
        .computeEnumSize(2, perSeriesAligner_);
    }
    if (crossSeriesReducer_ != com.google.monitoring.v3.Aggregation.Reducer.REDUCE_NONE.getNumber()) {
      size += com.google.protobuf.CodedOutputStream
        .computeEnumSize(4, crossSeriesReducer_);
    }
    {
      int dataSize = 0;
      for (int i = 0; i < groupByFields_.size(); i++) {
        dataSize += computeStringSizeNoTag(groupByFields_.getRaw(i));
      }
      size += dataSize;
      size += 1 * getGroupByFieldsList().size();
    }
    size += unknownFields.getSerializedSize();
    memoizedSize = size;
    return size;
  }

  @java.lang.Override
  public boolean equals(final java.lang.Object obj) {
    if (obj == this) {
     return true;
    }
    if (!(obj instanceof com.google.monitoring.v3.Aggregation)) {
      return super.equals(obj);
    }
    com.google.monitoring.v3.Aggregation other = (com.google.monitoring.v3.Aggregation) obj;

    boolean result = true;
    result = result && (hasAlignmentPeriod() == other.hasAlignmentPeriod());
    if (hasAlignmentPeriod()) {
      result = result && getAlignmentPeriod()
          .equals(other.getAlignmentPeriod());
    }
    result = result && perSeriesAligner_ == other.perSeriesAligner_;
    result = result && crossSeriesReducer_ == other.crossSeriesReducer_;
    result = result && getGroupByFieldsList()
        .equals(other.getGroupByFieldsList());
    result = result && unknownFields.equals(other.unknownFields);
    return result;
  }

  @java.lang.Override
  public int hashCode() {
    if (memoizedHashCode != 0) {
      return memoizedHashCode;
    }
    int hash = 41;
    hash = (19 * hash) + getDescriptor().hashCode();
    if (hasAlignmentPeriod()) {
      hash = (37 * hash) + ALIGNMENT_PERIOD_FIELD_NUMBER;
      hash = (53 * hash) + getAlignmentPeriod().hashCode();
    }
    hash = (37 * hash) + PER_SERIES_ALIGNER_FIELD_NUMBER;
    hash = (53 * hash) + perSeriesAligner_;
    hash = (37 * hash) + CROSS_SERIES_REDUCER_FIELD_NUMBER;
    hash = (53 * hash) + crossSeriesReducer_;
    if (getGroupByFieldsCount() > 0) {
      hash = (37 * hash) + GROUP_BY_FIELDS_FIELD_NUMBER;
      hash = (53 * hash) + getGroupByFieldsList().hashCode();
    }
    hash = (29 * hash) + unknownFields.hashCode();
    memoizedHashCode = hash;
    return hash;
  }

  public static com.google.monitoring.v3.Aggregation parseFrom(
      java.nio.ByteBuffer data)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data);
  }
  public static com.google.monitoring.v3.Aggregation parseFrom(
      java.nio.ByteBuffer data,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data, extensionRegistry);
  }
  public static com.google.monitoring.v3.Aggregation parseFrom(
      com.google.protobuf.ByteString data)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data);
  }
  public static com.google.monitoring.v3.Aggregation parseFrom(
      com.google.protobuf.ByteString data,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data, extensionRegistry);
  }
  public static com.google.monitoring.v3.Aggregation parseFrom(byte[] data)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data);
  }
  public static com.google.monitoring.v3.Aggregation parseFrom(
      byte[] data,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data, extensionRegistry);
  }
  public static com.google.monitoring.v3.Aggregation parseFrom(java.io.InputStream input)
      throws java.io.IOException {
    return com.google.protobuf.GeneratedMessageV3
        .parseWithIOException(PARSER, input);
  }
  public static com.google.monitoring.v3.Aggregation parseFrom(
      java.io.InputStream input,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws java.io.IOException {
    return com.google.protobuf.GeneratedMessageV3
        .parseWithIOException(PARSER, input, extensionRegistry);
  }
  public static com.google.monitoring.v3.Aggregation parseDelimitedFrom(java.io.InputStream input)
      throws java.io.IOException {
    return com.google.protobuf.GeneratedMessageV3
        .parseDelimitedWithIOException(PARSER, input);
  }
  public static com.google.monitoring.v3.Aggregation parseDelimitedFrom(
      java.io.InputStream input,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws java.io.IOException {
    return com.google.protobuf.GeneratedMessageV3
        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
  }
  public static com.google.monitoring.v3.Aggregation parseFrom(
      com.google.protobuf.CodedInputStream input)
      throws java.io.IOException {
    return com.google.protobuf.GeneratedMessageV3
        .parseWithIOException(PARSER, input);
  }
  public static com.google.monitoring.v3.Aggregation parseFrom(
      com.google.protobuf.CodedInputStream input,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws java.io.IOException {
    return com.google.protobuf.GeneratedMessageV3
        .parseWithIOException(PARSER, input, extensionRegistry);
  }

  public Builder newBuilderForType() { return newBuilder(); }
  public static Builder newBuilder() {
    return DEFAULT_INSTANCE.toBuilder();
  }
  public static Builder newBuilder(com.google.monitoring.v3.Aggregation prototype) {
    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
  }
  public Builder toBuilder() {
    return this == DEFAULT_INSTANCE
        ? new Builder() : new Builder().mergeFrom(this);
  }

  @java.lang.Override
  protected Builder newBuilderForType(
      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
    Builder builder = new Builder(parent);
    return builder;
  }
  /**
   * <pre>
   * Describes how to combine multiple time series to provide different views of
   * the data.  Aggregation consists of an alignment step on individual time
   * series (`alignment_period` and `per_series_aligner`) followed by an optional
   * reduction step of the data across the aligned time series
   * (`cross_series_reducer` and `group_by_fields`).  For more details, see
   * [Aggregation](/monitoring/api/learn_more#aggregation).
   * </pre>
   *
   * Protobuf type {@code google.monitoring.v3.Aggregation}
   */
  public static final class Builder extends
      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
      // @@protoc_insertion_point(builder_implements:google.monitoring.v3.Aggregation)
      com.google.monitoring.v3.AggregationOrBuilder {
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return com.google.monitoring.v3.CommonProto.internal_static_google_monitoring_v3_Aggregation_descriptor;
    }

    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return com.google.monitoring.v3.CommonProto.internal_static_google_monitoring_v3_Aggregation_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              com.google.monitoring.v3.Aggregation.class, com.google.monitoring.v3.Aggregation.Builder.class);
    }

    // Construct using com.google.monitoring.v3.Aggregation.newBuilder()
    private Builder() {
      maybeForceBuilderInitialization();
    }

    private Builder(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      super(parent);
      maybeForceBuilderInitialization();
    }
    private void maybeForceBuilderInitialization() {
      if (com.google.protobuf.GeneratedMessageV3
              .alwaysUseFieldBuilders) {
      }
    }
    public Builder clear() {
      super.clear();
      if (alignmentPeriodBuilder_ == null) {
        alignmentPeriod_ = null;
      } else {
        alignmentPeriod_ = null;
        alignmentPeriodBuilder_ = null;
      }
      perSeriesAligner_ = 0;

      crossSeriesReducer_ = 0;

      groupByFields_ = com.google.protobuf.LazyStringArrayList.EMPTY;
      bitField0_ = (bitField0_ & ~0x00000008);
      return this;
    }

    public com.google.protobuf.Descriptors.Descriptor
        getDescriptorForType() {
      return com.google.monitoring.v3.CommonProto.internal_static_google_monitoring_v3_Aggregation_descriptor;
    }

    public com.google.monitoring.v3.Aggregation getDefaultInstanceForType() {
      return com.google.monitoring.v3.Aggregation.getDefaultInstance();
    }

    public com.google.monitoring.v3.Aggregation build() {
      com.google.monitoring.v3.Aggregation result = buildPartial();
      if (!result.isInitialized()) {
        throw newUninitializedMessageException(result);
      }
      return result;
    }

    public com.google.monitoring.v3.Aggregation buildPartial() {
      com.google.monitoring.v3.Aggregation result = new com.google.monitoring.v3.Aggregation(this);
      int from_bitField0_ = bitField0_;
      int to_bitField0_ = 0;
      if (alignmentPeriodBuilder_ == null) {
        result.alignmentPeriod_ = alignmentPeriod_;
      } else {
        result.alignmentPeriod_ = alignmentPeriodBuilder_.build();
      }
      result.perSeriesAligner_ = perSeriesAligner_;
      result.crossSeriesReducer_ = crossSeriesReducer_;
      if (((bitField0_ & 0x00000008) == 0x00000008)) {
        groupByFields_ = groupByFields_.getUnmodifiableView();
        bitField0_ = (bitField0_ & ~0x00000008);
      }
      result.groupByFields_ = groupByFields_;
      result.bitField0_ = to_bitField0_;
      onBuilt();
      return result;
    }

    public Builder clone() {
      return (Builder) super.clone();
    }
    public Builder setField(
        com.google.protobuf.Descriptors.FieldDescriptor field,
        java.lang.Object value) {
      return (Builder) super.setField(field, value);
    }
    public Builder clearField(
        com.google.protobuf.Descriptors.FieldDescriptor field) {
      return (Builder) super.clearField(field);
    }
    public Builder clearOneof(
        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
      return (Builder) super.clearOneof(oneof);
    }
    public Builder setRepeatedField(
        com.google.protobuf.Descriptors.FieldDescriptor field,
        int index, java.lang.Object value) {
      return (Builder) super.setRepeatedField(field, index, value);
    }
    public Builder addRepeatedField(
        com.google.protobuf.Descriptors.FieldDescriptor field,
        java.lang.Object value) {
      return (Builder) super.addRepeatedField(field, value);
    }
    public Builder mergeFrom(com.google.protobuf.Message other) {
      if (other instanceof com.google.monitoring.v3.Aggregation) {
        return mergeFrom((com.google.monitoring.v3.Aggregation)other);
      } else {
        super.mergeFrom(other);
        return this;
      }
    }

    public Builder mergeFrom(com.google.monitoring.v3.Aggregation other) {
      if (other == com.google.monitoring.v3.Aggregation.getDefaultInstance()) return this;
      if (other.hasAlignmentPeriod()) {
        mergeAlignmentPeriod(other.getAlignmentPeriod());
      }
      if (other.perSeriesAligner_ != 0) {
        setPerSeriesAlignerValue(other.getPerSeriesAlignerValue());
      }
      if (other.crossSeriesReducer_ != 0) {
        setCrossSeriesReducerValue(other.getCrossSeriesReducerValue());
      }
      if (!other.groupByFields_.isEmpty()) {
        if (groupByFields_.isEmpty()) {
          groupByFields_ = other.groupByFields_;
          bitField0_ = (bitField0_ & ~0x00000008);
        } else {
          ensureGroupByFieldsIsMutable();
          groupByFields_.addAll(other.groupByFields_);
        }
        onChanged();
      }
      this.mergeUnknownFields(other.unknownFields);
      onChanged();
      return this;
    }

    public final boolean isInitialized() {
      return true;
    }

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

    private com.google.protobuf.Duration alignmentPeriod_ = null;
    private com.google.protobuf.SingleFieldBuilderV3<
        com.google.protobuf.Duration, com.google.protobuf.Duration.Builder, com.google.protobuf.DurationOrBuilder> alignmentPeriodBuilder_;
    /**
     * <pre>
     * The alignment period for per-[time series][google.monitoring.v3.TimeSeries]
     * alignment. If present, `alignmentPeriod` must be at least 60
     * seconds.  After per-time series alignment, each time series will
     * contain data points only on the period boundaries. If
     * `perSeriesAligner` is not specified or equals `ALIGN_NONE`, then
     * this field is ignored. If `perSeriesAligner` is specified and
     * does not equal `ALIGN_NONE`, then this field must be defined;
     * otherwise an error is returned.
     * </pre>
     *
     * <code>.google.protobuf.Duration alignment_period = 1;</code>
     */
    public boolean hasAlignmentPeriod() {
      return alignmentPeriodBuilder_ != null || alignmentPeriod_ != null;
    }
    /**
     * <pre>
     * The alignment period for per-[time series][google.monitoring.v3.TimeSeries]
     * alignment. If present, `alignmentPeriod` must be at least 60
     * seconds.  After per-time series alignment, each time series will
     * contain data points only on the period boundaries. If
     * `perSeriesAligner` is not specified or equals `ALIGN_NONE`, then
     * this field is ignored. If `perSeriesAligner` is specified and
     * does not equal `ALIGN_NONE`, then this field must be defined;
     * otherwise an error is returned.
     * </pre>
     *
     * <code>.google.protobuf.Duration alignment_period = 1;</code>
     */
    public com.google.protobuf.Duration getAlignmentPeriod() {
      if (alignmentPeriodBuilder_ == null) {
        return alignmentPeriod_ == null ? com.google.protobuf.Duration.getDefaultInstance() : alignmentPeriod_;
      } else {
        return alignmentPeriodBuilder_.getMessage();
      }
    }
    /**
     * <pre>
     * The alignment period for per-[time series][google.monitoring.v3.TimeSeries]
     * alignment. If present, `alignmentPeriod` must be at least 60
     * seconds.  After per-time series alignment, each time series will
     * contain data points only on the period boundaries. If
     * `perSeriesAligner` is not specified or equals `ALIGN_NONE`, then
     * this field is ignored. If `perSeriesAligner` is specified and
     * does not equal `ALIGN_NONE`, then this field must be defined;
     * otherwise an error is returned.
     * </pre>
     *
     * <code>.google.protobuf.Duration alignment_period = 1;</code>
     */
    public Builder setAlignmentPeriod(com.google.protobuf.Duration value) {
      if (alignmentPeriodBuilder_ == null) {
        if (value == null) {
          throw new NullPointerException();
        }
        alignmentPeriod_ = value;
        onChanged();
      } else {
        alignmentPeriodBuilder_.setMessage(value);
      }

      return this;
    }
    /**
     * <pre>
     * The alignment period for per-[time series][google.monitoring.v3.TimeSeries]
     * alignment. If present, `alignmentPeriod` must be at least 60
     * seconds.  After per-time series alignment, each time series will
     * contain data points only on the period boundaries. If
     * `perSeriesAligner` is not specified or equals `ALIGN_NONE`, then
     * this field is ignored. If `perSeriesAligner` is specified and
     * does not equal `ALIGN_NONE`, then this field must be defined;
     * otherwise an error is returned.
     * </pre>
     *
     * <code>.google.protobuf.Duration alignment_period = 1;</code>
     */
    public Builder setAlignmentPeriod(
        com.google.protobuf.Duration.Builder builderForValue) {
      if (alignmentPeriodBuilder_ == null) {
        alignmentPeriod_ = builderForValue.build();
        onChanged();
      } else {
        alignmentPeriodBuilder_.setMessage(builderForValue.build());
      }

      return this;
    }
    /**
     * <pre>
     * The alignment period for per-[time series][google.monitoring.v3.TimeSeries]
     * alignment. If present, `alignmentPeriod` must be at least 60
     * seconds.  After per-time series alignment, each time series will
     * contain data points only on the period boundaries. If
     * `perSeriesAligner` is not specified or equals `ALIGN_NONE`, then
     * this field is ignored. If `perSeriesAligner` is specified and
     * does not equal `ALIGN_NONE`, then this field must be defined;
     * otherwise an error is returned.
     * </pre>
     *
     * <code>.google.protobuf.Duration alignment_period = 1;</code>
     */
    public Builder mergeAlignmentPeriod(com.google.protobuf.Duration value) {
      if (alignmentPeriodBuilder_ == null) {
        if (alignmentPeriod_ != null) {
          alignmentPeriod_ =
            com.google.protobuf.Duration.newBuilder(alignmentPeriod_).mergeFrom(value).buildPartial();
        } else {
          alignmentPeriod_ = value;
        }
        onChanged();
      } else {
        alignmentPeriodBuilder_.mergeFrom(value);
      }

      return this;
    }
    /**
     * <pre>
     * The alignment period for per-[time series][google.monitoring.v3.TimeSeries]
     * alignment. If present, `alignmentPeriod` must be at least 60
     * seconds.  After per-time series alignment, each time series will
     * contain data points only on the period boundaries. If
     * `perSeriesAligner` is not specified or equals `ALIGN_NONE`, then
     * this field is ignored. If `perSeriesAligner` is specified and
     * does not equal `ALIGN_NONE`, then this field must be defined;
     * otherwise an error is returned.
     * </pre>
     *
     * <code>.google.protobuf.Duration alignment_period = 1;</code>
     */
    public Builder clearAlignmentPeriod() {
      if (alignmentPeriodBuilder_ == null) {
        alignmentPeriod_ = null;
        onChanged();
      } else {
        alignmentPeriod_ = null;
        alignmentPeriodBuilder_ = null;
      }

      return this;
    }
    /**
     * <pre>
     * The alignment period for per-[time series][google.monitoring.v3.TimeSeries]
     * alignment. If present, `alignmentPeriod` must be at least 60
     * seconds.  After per-time series alignment, each time series will
     * contain data points only on the period boundaries. If
     * `perSeriesAligner` is not specified or equals `ALIGN_NONE`, then
     * this field is ignored. If `perSeriesAligner` is specified and
     * does not equal `ALIGN_NONE`, then this field must be defined;
     * otherwise an error is returned.
     * </pre>
     *
     * <code>.google.protobuf.Duration alignment_period = 1;</code>
     */
    public com.google.protobuf.Duration.Builder getAlignmentPeriodBuilder() {
      
      onChanged();
      return getAlignmentPeriodFieldBuilder().getBuilder();
    }
    /**
     * <pre>
     * The alignment period for per-[time series][google.monitoring.v3.TimeSeries]
     * alignment. If present, `alignmentPeriod` must be at least 60
     * seconds.  After per-time series alignment, each time series will
     * contain data points only on the period boundaries. If
     * `perSeriesAligner` is not specified or equals `ALIGN_NONE`, then
     * this field is ignored. If `perSeriesAligner` is specified and
     * does not equal `ALIGN_NONE`, then this field must be defined;
     * otherwise an error is returned.
     * </pre>
     *
     * <code>.google.protobuf.Duration alignment_period = 1;</code>
     */
    public com.google.protobuf.DurationOrBuilder getAlignmentPeriodOrBuilder() {
      if (alignmentPeriodBuilder_ != null) {
        return alignmentPeriodBuilder_.getMessageOrBuilder();
      } else {
        return alignmentPeriod_ == null ?
            com.google.protobuf.Duration.getDefaultInstance() : alignmentPeriod_;
      }
    }
    /**
     * <pre>
     * The alignment period for per-[time series][google.monitoring.v3.TimeSeries]
     * alignment. If present, `alignmentPeriod` must be at least 60
     * seconds.  After per-time series alignment, each time series will
     * contain data points only on the period boundaries. If
     * `perSeriesAligner` is not specified or equals `ALIGN_NONE`, then
     * this field is ignored. If `perSeriesAligner` is specified and
     * does not equal `ALIGN_NONE`, then this field must be defined;
     * otherwise an error is returned.
     * </pre>
     *
     * <code>.google.protobuf.Duration alignment_period = 1;</code>
     */
    private com.google.protobuf.SingleFieldBuilderV3<
        com.google.protobuf.Duration, com.google.protobuf.Duration.Builder, com.google.protobuf.DurationOrBuilder> 
        getAlignmentPeriodFieldBuilder() {
      if (alignmentPeriodBuilder_ == null) {
        alignmentPeriodBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
            com.google.protobuf.Duration, com.google.protobuf.Duration.Builder, com.google.protobuf.DurationOrBuilder>(
                getAlignmentPeriod(),
                getParentForChildren(),
                isClean());
        alignmentPeriod_ = null;
      }
      return alignmentPeriodBuilder_;
    }

    private int perSeriesAligner_ = 0;
    /**
     * <pre>
     * The approach to be used to align individual time series. Not all
     * alignment functions may be applied to all time series, depending
     * on the metric type and value type of the original time
     * series. Alignment may change the metric type or the value type of
     * the time series.
     * Time series data must be aligned in order to perform cross-time
     * series reduction. If `crossSeriesReducer` is specified, then
     * `perSeriesAligner` must be specified and not equal `ALIGN_NONE`
     * and `alignmentPeriod` must be specified; otherwise, an error is
     * returned.
     * </pre>
     *
     * <code>.google.monitoring.v3.Aggregation.Aligner per_series_aligner = 2;</code>
     */
    public int getPerSeriesAlignerValue() {
      return perSeriesAligner_;
    }
    /**
     * <pre>
     * The approach to be used to align individual time series. Not all
     * alignment functions may be applied to all time series, depending
     * on the metric type and value type of the original time
     * series. Alignment may change the metric type or the value type of
     * the time series.
     * Time series data must be aligned in order to perform cross-time
     * series reduction. If `crossSeriesReducer` is specified, then
     * `perSeriesAligner` must be specified and not equal `ALIGN_NONE`
     * and `alignmentPeriod` must be specified; otherwise, an error is
     * returned.
     * </pre>
     *
     * <code>.google.monitoring.v3.Aggregation.Aligner per_series_aligner = 2;</code>
     */
    public Builder setPerSeriesAlignerValue(int value) {
      perSeriesAligner_ = value;
      onChanged();
      return this;
    }
    /**
     * <pre>
     * The approach to be used to align individual time series. Not all
     * alignment functions may be applied to all time series, depending
     * on the metric type and value type of the original time
     * series. Alignment may change the metric type or the value type of
     * the time series.
     * Time series data must be aligned in order to perform cross-time
     * series reduction. If `crossSeriesReducer` is specified, then
     * `perSeriesAligner` must be specified and not equal `ALIGN_NONE`
     * and `alignmentPeriod` must be specified; otherwise, an error is
     * returned.
     * </pre>
     *
     * <code>.google.monitoring.v3.Aggregation.Aligner per_series_aligner = 2;</code>
     */
    public com.google.monitoring.v3.Aggregation.Aligner getPerSeriesAligner() {
      com.google.monitoring.v3.Aggregation.Aligner result = com.google.monitoring.v3.Aggregation.Aligner.valueOf(perSeriesAligner_);
      return result == null ? com.google.monitoring.v3.Aggregation.Aligner.UNRECOGNIZED : result;
    }
    /**
     * <pre>
     * The approach to be used to align individual time series. Not all
     * alignment functions may be applied to all time series, depending
     * on the metric type and value type of the original time
     * series. Alignment may change the metric type or the value type of
     * the time series.
     * Time series data must be aligned in order to perform cross-time
     * series reduction. If `crossSeriesReducer` is specified, then
     * `perSeriesAligner` must be specified and not equal `ALIGN_NONE`
     * and `alignmentPeriod` must be specified; otherwise, an error is
     * returned.
     * </pre>
     *
     * <code>.google.monitoring.v3.Aggregation.Aligner per_series_aligner = 2;</code>
     */
    public Builder setPerSeriesAligner(com.google.monitoring.v3.Aggregation.Aligner value) {
      if (value == null) {
        throw new NullPointerException();
      }
      
      perSeriesAligner_ = value.getNumber();
      onChanged();
      return this;
    }
    /**
     * <pre>
     * The approach to be used to align individual time series. Not all
     * alignment functions may be applied to all time series, depending
     * on the metric type and value type of the original time
     * series. Alignment may change the metric type or the value type of
     * the time series.
     * Time series data must be aligned in order to perform cross-time
     * series reduction. If `crossSeriesReducer` is specified, then
     * `perSeriesAligner` must be specified and not equal `ALIGN_NONE`
     * and `alignmentPeriod` must be specified; otherwise, an error is
     * returned.
     * </pre>
     *
     * <code>.google.monitoring.v3.Aggregation.Aligner per_series_aligner = 2;</code>
     */
    public Builder clearPerSeriesAligner() {
      
      perSeriesAligner_ = 0;
      onChanged();
      return this;
    }

    private int crossSeriesReducer_ = 0;
    /**
     * <pre>
     * The approach to be used to combine time series. Not all reducer
     * functions may be applied to all time series, depending on the
     * metric type and the value type of the original time
     * series. Reduction may change the metric type of value type of the
     * time series.
     * Time series data must be aligned in order to perform cross-time
     * series reduction. If `crossSeriesReducer` is specified, then
     * `perSeriesAligner` must be specified and not equal `ALIGN_NONE`
     * and `alignmentPeriod` must be specified; otherwise, an error is
     * returned.
     * </pre>
     *
     * <code>.google.monitoring.v3.Aggregation.Reducer cross_series_reducer = 4;</code>
     */
    public int getCrossSeriesReducerValue() {
      return crossSeriesReducer_;
    }
    /**
     * <pre>
     * The approach to be used to combine time series. Not all reducer
     * functions may be applied to all time series, depending on the
     * metric type and the value type of the original time
     * series. Reduction may change the metric type of value type of the
     * time series.
     * Time series data must be aligned in order to perform cross-time
     * series reduction. If `crossSeriesReducer` is specified, then
     * `perSeriesAligner` must be specified and not equal `ALIGN_NONE`
     * and `alignmentPeriod` must be specified; otherwise, an error is
     * returned.
     * </pre>
     *
     * <code>.google.monitoring.v3.Aggregation.Reducer cross_series_reducer = 4;</code>
     */
    public Builder setCrossSeriesReducerValue(int value) {
      crossSeriesReducer_ = value;
      onChanged();
      return this;
    }
    /**
     * <pre>
     * The approach to be used to combine time series. Not all reducer
     * functions may be applied to all time series, depending on the
     * metric type and the value type of the original time
     * series. Reduction may change the metric type of value type of the
     * time series.
     * Time series data must be aligned in order to perform cross-time
     * series reduction. If `crossSeriesReducer` is specified, then
     * `perSeriesAligner` must be specified and not equal `ALIGN_NONE`
     * and `alignmentPeriod` must be specified; otherwise, an error is
     * returned.
     * </pre>
     *
     * <code>.google.monitoring.v3.Aggregation.Reducer cross_series_reducer = 4;</code>
     */
    public com.google.monitoring.v3.Aggregation.Reducer getCrossSeriesReducer() {
      com.google.monitoring.v3.Aggregation.Reducer result = com.google.monitoring.v3.Aggregation.Reducer.valueOf(crossSeriesReducer_);
      return result == null ? com.google.monitoring.v3.Aggregation.Reducer.UNRECOGNIZED : result;
    }
    /**
     * <pre>
     * The approach to be used to combine time series. Not all reducer
     * functions may be applied to all time series, depending on the
     * metric type and the value type of the original time
     * series. Reduction may change the metric type of value type of the
     * time series.
     * Time series data must be aligned in order to perform cross-time
     * series reduction. If `crossSeriesReducer` is specified, then
     * `perSeriesAligner` must be specified and not equal `ALIGN_NONE`
     * and `alignmentPeriod` must be specified; otherwise, an error is
     * returned.
     * </pre>
     *
     * <code>.google.monitoring.v3.Aggregation.Reducer cross_series_reducer = 4;</code>
     */
    public Builder setCrossSeriesReducer(com.google.monitoring.v3.Aggregation.Reducer value) {
      if (value == null) {
        throw new NullPointerException();
      }
      
      crossSeriesReducer_ = value.getNumber();
      onChanged();
      return this;
    }
    /**
     * <pre>
     * The approach to be used to combine time series. Not all reducer
     * functions may be applied to all time series, depending on the
     * metric type and the value type of the original time
     * series. Reduction may change the metric type of value type of the
     * time series.
     * Time series data must be aligned in order to perform cross-time
     * series reduction. If `crossSeriesReducer` is specified, then
     * `perSeriesAligner` must be specified and not equal `ALIGN_NONE`
     * and `alignmentPeriod` must be specified; otherwise, an error is
     * returned.
     * </pre>
     *
     * <code>.google.monitoring.v3.Aggregation.Reducer cross_series_reducer = 4;</code>
     */
    public Builder clearCrossSeriesReducer() {
      
      crossSeriesReducer_ = 0;
      onChanged();
      return this;
    }

    private com.google.protobuf.LazyStringList groupByFields_ = com.google.protobuf.LazyStringArrayList.EMPTY;
    private void ensureGroupByFieldsIsMutable() {
      if (!((bitField0_ & 0x00000008) == 0x00000008)) {
        groupByFields_ = new com.google.protobuf.LazyStringArrayList(groupByFields_);
        bitField0_ |= 0x00000008;
       }
    }
    /**
     * <pre>
     * The set of fields to preserve when `crossSeriesReducer` is
     * specified. The `groupByFields` determine how the time series are
     * partitioned into subsets prior to applying the aggregation
     * function. Each subset contains time series that have the same
     * value for each of the grouping fields. Each individual time
     * series is a member of exactly one subset. The
     * `crossSeriesReducer` is applied to each subset of time series.
     * It is not possible to reduce across different resource types, so
     * this field implicitly contains `resource.type`.  Fields not
     * specified in `groupByFields` are aggregated away.  If
     * `groupByFields` is not specified and all the time series have
     * the same resource type, then the time series are aggregated into
     * a single output time series. If `crossSeriesReducer` is not
     * defined, this field is ignored.
     * </pre>
     *
     * <code>repeated string group_by_fields = 5;</code>
     */
    public com.google.protobuf.ProtocolStringList
        getGroupByFieldsList() {
      return groupByFields_.getUnmodifiableView();
    }
    /**
     * <pre>
     * The set of fields to preserve when `crossSeriesReducer` is
     * specified. The `groupByFields` determine how the time series are
     * partitioned into subsets prior to applying the aggregation
     * function. Each subset contains time series that have the same
     * value for each of the grouping fields. Each individual time
     * series is a member of exactly one subset. The
     * `crossSeriesReducer` is applied to each subset of time series.
     * It is not possible to reduce across different resource types, so
     * this field implicitly contains `resource.type`.  Fields not
     * specified in `groupByFields` are aggregated away.  If
     * `groupByFields` is not specified and all the time series have
     * the same resource type, then the time series are aggregated into
     * a single output time series. If `crossSeriesReducer` is not
     * defined, this field is ignored.
     * </pre>
     *
     * <code>repeated string group_by_fields = 5;</code>
     */
    public int getGroupByFieldsCount() {
      return groupByFields_.size();
    }
    /**
     * <pre>
     * The set of fields to preserve when `crossSeriesReducer` is
     * specified. The `groupByFields` determine how the time series are
     * partitioned into subsets prior to applying the aggregation
     * function. Each subset contains time series that have the same
     * value for each of the grouping fields. Each individual time
     * series is a member of exactly one subset. The
     * `crossSeriesReducer` is applied to each subset of time series.
     * It is not possible to reduce across different resource types, so
     * this field implicitly contains `resource.type`.  Fields not
     * specified in `groupByFields` are aggregated away.  If
     * `groupByFields` is not specified and all the time series have
     * the same resource type, then the time series are aggregated into
     * a single output time series. If `crossSeriesReducer` is not
     * defined, this field is ignored.
     * </pre>
     *
     * <code>repeated string group_by_fields = 5;</code>
     */
    public java.lang.String getGroupByFields(int index) {
      return groupByFields_.get(index);
    }
    /**
     * <pre>
     * The set of fields to preserve when `crossSeriesReducer` is
     * specified. The `groupByFields` determine how the time series are
     * partitioned into subsets prior to applying the aggregation
     * function. Each subset contains time series that have the same
     * value for each of the grouping fields. Each individual time
     * series is a member of exactly one subset. The
     * `crossSeriesReducer` is applied to each subset of time series.
     * It is not possible to reduce across different resource types, so
     * this field implicitly contains `resource.type`.  Fields not
     * specified in `groupByFields` are aggregated away.  If
     * `groupByFields` is not specified and all the time series have
     * the same resource type, then the time series are aggregated into
     * a single output time series. If `crossSeriesReducer` is not
     * defined, this field is ignored.
     * </pre>
     *
     * <code>repeated string group_by_fields = 5;</code>
     */
    public com.google.protobuf.ByteString
        getGroupByFieldsBytes(int index) {
      return groupByFields_.getByteString(index);
    }
    /**
     * <pre>
     * The set of fields to preserve when `crossSeriesReducer` is
     * specified. The `groupByFields` determine how the time series are
     * partitioned into subsets prior to applying the aggregation
     * function. Each subset contains time series that have the same
     * value for each of the grouping fields. Each individual time
     * series is a member of exactly one subset. The
     * `crossSeriesReducer` is applied to each subset of time series.
     * It is not possible to reduce across different resource types, so
     * this field implicitly contains `resource.type`.  Fields not
     * specified in `groupByFields` are aggregated away.  If
     * `groupByFields` is not specified and all the time series have
     * the same resource type, then the time series are aggregated into
     * a single output time series. If `crossSeriesReducer` is not
     * defined, this field is ignored.
     * </pre>
     *
     * <code>repeated string group_by_fields = 5;</code>
     */
    public Builder setGroupByFields(
        int index, java.lang.String value) {
      if (value == null) {
    throw new NullPointerException();
  }
  ensureGroupByFieldsIsMutable();
      groupByFields_.set(index, value);
      onChanged();
      return this;
    }
    /**
     * <pre>
     * The set of fields to preserve when `crossSeriesReducer` is
     * specified. The `groupByFields` determine how the time series are
     * partitioned into subsets prior to applying the aggregation
     * function. Each subset contains time series that have the same
     * value for each of the grouping fields. Each individual time
     * series is a member of exactly one subset. The
     * `crossSeriesReducer` is applied to each subset of time series.
     * It is not possible to reduce across different resource types, so
     * this field implicitly contains `resource.type`.  Fields not
     * specified in `groupByFields` are aggregated away.  If
     * `groupByFields` is not specified and all the time series have
     * the same resource type, then the time series are aggregated into
     * a single output time series. If `crossSeriesReducer` is not
     * defined, this field is ignored.
     * </pre>
     *
     * <code>repeated string group_by_fields = 5;</code>
     */
    public Builder addGroupByFields(
        java.lang.String value) {
      if (value == null) {
    throw new NullPointerException();
  }
  ensureGroupByFieldsIsMutable();
      groupByFields_.add(value);
      onChanged();
      return this;
    }
    /**
     * <pre>
     * The set of fields to preserve when `crossSeriesReducer` is
     * specified. The `groupByFields` determine how the time series are
     * partitioned into subsets prior to applying the aggregation
     * function. Each subset contains time series that have the same
     * value for each of the grouping fields. Each individual time
     * series is a member of exactly one subset. The
     * `crossSeriesReducer` is applied to each subset of time series.
     * It is not possible to reduce across different resource types, so
     * this field implicitly contains `resource.type`.  Fields not
     * specified in `groupByFields` are aggregated away.  If
     * `groupByFields` is not specified and all the time series have
     * the same resource type, then the time series are aggregated into
     * a single output time series. If `crossSeriesReducer` is not
     * defined, this field is ignored.
     * </pre>
     *
     * <code>repeated string group_by_fields = 5;</code>
     */
    public Builder addAllGroupByFields(
        java.lang.Iterable<java.lang.String> values) {
      ensureGroupByFieldsIsMutable();
      com.google.protobuf.AbstractMessageLite.Builder.addAll(
          values, groupByFields_);
      onChanged();
      return this;
    }
    /**
     * <pre>
     * The set of fields to preserve when `crossSeriesReducer` is
     * specified. The `groupByFields` determine how the time series are
     * partitioned into subsets prior to applying the aggregation
     * function. Each subset contains time series that have the same
     * value for each of the grouping fields. Each individual time
     * series is a member of exactly one subset. The
     * `crossSeriesReducer` is applied to each subset of time series.
     * It is not possible to reduce across different resource types, so
     * this field implicitly contains `resource.type`.  Fields not
     * specified in `groupByFields` are aggregated away.  If
     * `groupByFields` is not specified and all the time series have
     * the same resource type, then the time series are aggregated into
     * a single output time series. If `crossSeriesReducer` is not
     * defined, this field is ignored.
     * </pre>
     *
     * <code>repeated string group_by_fields = 5;</code>
     */
    public Builder clearGroupByFields() {
      groupByFields_ = com.google.protobuf.LazyStringArrayList.EMPTY;
      bitField0_ = (bitField0_ & ~0x00000008);
      onChanged();
      return this;
    }
    /**
     * <pre>
     * The set of fields to preserve when `crossSeriesReducer` is
     * specified. The `groupByFields` determine how the time series are
     * partitioned into subsets prior to applying the aggregation
     * function. Each subset contains time series that have the same
     * value for each of the grouping fields. Each individual time
     * series is a member of exactly one subset. The
     * `crossSeriesReducer` is applied to each subset of time series.
     * It is not possible to reduce across different resource types, so
     * this field implicitly contains `resource.type`.  Fields not
     * specified in `groupByFields` are aggregated away.  If
     * `groupByFields` is not specified and all the time series have
     * the same resource type, then the time series are aggregated into
     * a single output time series. If `crossSeriesReducer` is not
     * defined, this field is ignored.
     * </pre>
     *
     * <code>repeated string group_by_fields = 5;</code>
     */
    public Builder addGroupByFieldsBytes(
        com.google.protobuf.ByteString value) {
      if (value == null) {
    throw new NullPointerException();
  }
  checkByteStringIsUtf8(value);
      ensureGroupByFieldsIsMutable();
      groupByFields_.add(value);
      onChanged();
      return this;
    }
    public final Builder setUnknownFields(
        final com.google.protobuf.UnknownFieldSet unknownFields) {
      return super.setUnknownFieldsProto3(unknownFields);
    }

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


    // @@protoc_insertion_point(builder_scope:google.monitoring.v3.Aggregation)
  }

  // @@protoc_insertion_point(class_scope:google.monitoring.v3.Aggregation)
  private static final com.google.monitoring.v3.Aggregation DEFAULT_INSTANCE;
  static {
    DEFAULT_INSTANCE = new com.google.monitoring.v3.Aggregation();
  }

  public static com.google.monitoring.v3.Aggregation getDefaultInstance() {
    return DEFAULT_INSTANCE;
  }

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

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

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

  public com.google.monitoring.v3.Aggregation getDefaultInstanceForType() {
    return DEFAULT_INSTANCE;
  }

}

