// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.api.generator.gapic.model;

import com.google.api.generator.engine.ast.TypeNode;
import com.google.auto.value.AutoValue;
import javax.annotation.Nullable;

@AutoValue
public abstract class Field {
  public abstract String name();

  public abstract TypeNode type();

  public abstract boolean isMessage();

  public abstract boolean isEnum();

  public abstract boolean isRepeated();

  public abstract boolean isMap();

  public abstract boolean isContainedInOneof();

  @Nullable
  public abstract ResourceReference resourceReference();

  @Nullable
  public abstract String description();

  public boolean hasDescription() {
    return description() != null;
  }

  public boolean hasResourceReference() {
    return type().equals(TypeNode.STRING) && resourceReference() != null;
  }

  public abstract Builder toBuilder();

  public static Builder builder() {
    return new AutoValue_Field.Builder()
        .setIsMessage(false)
        .setIsEnum(false)
        .setIsRepeated(false)
        .setIsMap(false)
        .setIsContainedInOneof(false);
  }

  @AutoValue.Builder
  public abstract static class Builder {
    public abstract Builder setName(String name);

    public abstract Builder setType(TypeNode type);

    public abstract Builder setIsMessage(boolean isMessage);

    public abstract Builder setIsEnum(boolean isEnum);

    public abstract Builder setIsRepeated(boolean isRepeated);

    public abstract Builder setIsMap(boolean isMap);

    public abstract Builder setIsContainedInOneof(boolean isContainedInOneof);

    public abstract Builder setResourceReference(ResourceReference resourceReference);

    public abstract Builder setDescription(String description);

    public abstract Field build();
  }
}

@@ -722,16 +722,42 @@
 oValue;%0A
+import java.util.Objects;%0A
 import j
@@ -1408,32 +1408,1056 @@
 ) != null;%0A  %7D%0A%0A
+  @Override%0A  public boolean equals(Object o) %7B%0A    if (!(o instanceof Field)) %7B%0A      return false;%0A    %7D%0A%0A    Field other = (Field) o;%0A    return name().equals(other.name())%0A        && type().equals(other.type())%0A        && isMessage() == other.isMessage()%0A        && isEnum() == other.isEnum()%0A        && isRepeated() == other.isRepeated()%0A        && isMap() == other.isMap()%0A        && isContainedInOneof() == other.isContainedInOneof()%0A        && Objects.equals(resourceReference(), other.resourceReference())%0A        && Objects.equals(description(), other.description());%0A  %7D%0A%0A  @Override%0A  public int hashCode() %7B%0A    return 17 * name().hashCode()%0A        + 19 * type().hashCode()%0A        + (isMessage() ? 1 : 0) * 23%0A        + (isEnum() ? 1 : 0) * 29%0A        + (isRepeated() ? 1 : 0) * 31%0A        + (isMap() ? 1 : 0) * 37%0A        + (isContainedInOneof() ? 1 : 0) * 41%0A        + (resourceReference() == null ? 0 : resourceReference().hashCode())%0A        + (description() == null ? 0 : description().hashCode());%0A  %7D%0A%0A
   public abstrac

add hashCode() and equals() to Field (#622)