1 // Copyright 2020 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 package com.google.api.generator.gapic.model;
16 
17 import com.google.api.generator.engine.ast.TypeNode;
18 import com.google.auto.value.AutoValue;
19 import java.util.Objects;
20 import java.util.Optional;
21 import javax.annotation.Nullable;
22 
23 @AutoValue
24 public abstract class Field {
25   // The field's canonical name, potentially post-processed by conflict resolution logic.
name()26   public abstract String name();
27 
28   // The field's name as it appeared in the protobuf.
29   // Not equal to name() only when there is a field name conflict, as per protoc's conflict
30   // resolution behavior. For more context, please see the invocation site of the setter method.
originalName()31   public abstract String originalName();
32 
type()33   public abstract TypeNode type();
34 
isMessage()35   public abstract boolean isMessage();
36 
isEnum()37   public abstract boolean isEnum();
38 
isRepeated()39   public abstract boolean isRepeated();
40 
isMap()41   public abstract boolean isMap();
42 
isContainedInOneof()43   public abstract boolean isContainedInOneof();
44 
isProto3Optional()45   public abstract boolean isProto3Optional();
46 
47   @Nullable
resourceReference()48   public abstract ResourceReference resourceReference();
49 
50   @Nullable
description()51   public abstract String description();
52 
hasFieldNameConflict()53   public boolean hasFieldNameConflict() {
54     return !name().equals(originalName());
55   }
56 
hasDescription()57   public boolean hasDescription() {
58     return description() != null;
59   }
60 
hasResourceReference()61   public boolean hasResourceReference() {
62     return type().equals(TypeNode.STRING) && resourceReference() != null;
63   }
64 
65   @Override
equals(Object o)66   public boolean equals(Object o) {
67     if (!(o instanceof Field)) {
68       return false;
69     }
70 
71     Field other = (Field) o;
72     return name().equals(other.name())
73         && originalName().equals(other.originalName())
74         && type().equals(other.type())
75         && isMessage() == other.isMessage()
76         && isEnum() == other.isEnum()
77         && isRepeated() == other.isRepeated()
78         && isMap() == other.isMap()
79         && isContainedInOneof() == other.isContainedInOneof()
80         && isProto3Optional() == other.isProto3Optional()
81         && Objects.equals(resourceReference(), other.resourceReference())
82         && Objects.equals(description(), other.description());
83   }
84 
85   @Override
hashCode()86   public int hashCode() {
87     return 17 * name().hashCode()
88         + 31 * originalName().hashCode()
89         + 19 * type().hashCode()
90         + (isMessage() ? 1 : 0) * 23
91         + (isEnum() ? 1 : 0) * 29
92         + (isRepeated() ? 1 : 0) * 31
93         + (isMap() ? 1 : 0) * 37
94         + (isContainedInOneof() ? 1 : 0) * 41
95         + (isProto3Optional() ? 1 : 0) * 43
96         + (resourceReference() == null ? 0 : resourceReference().hashCode())
97         + (description() == null ? 0 : description().hashCode());
98   }
99 
toBuilder()100   public abstract Builder toBuilder();
101 
builder()102   public static Builder builder() {
103     return new AutoValue_Field.Builder()
104         .setIsMessage(false)
105         .setIsEnum(false)
106         .setIsRepeated(false)
107         .setIsMap(false)
108         .setIsContainedInOneof(false)
109         .setIsProto3Optional(false);
110   }
111 
112   @AutoValue.Builder
113   public abstract static class Builder {
setName(String name)114     public abstract Builder setName(String name);
115 
setOriginalName(String originalName)116     public abstract Builder setOriginalName(String originalName);
117 
setType(TypeNode type)118     public abstract Builder setType(TypeNode type);
119 
setIsMessage(boolean isMessage)120     public abstract Builder setIsMessage(boolean isMessage);
121 
setIsEnum(boolean isEnum)122     public abstract Builder setIsEnum(boolean isEnum);
123 
setIsRepeated(boolean isRepeated)124     public abstract Builder setIsRepeated(boolean isRepeated);
125 
setIsMap(boolean isMap)126     public abstract Builder setIsMap(boolean isMap);
127 
setIsContainedInOneof(boolean isContainedInOneof)128     public abstract Builder setIsContainedInOneof(boolean isContainedInOneof);
129 
setIsProto3Optional(boolean isProto3Optional)130     public abstract Builder setIsProto3Optional(boolean isProto3Optional);
131 
setResourceReference(ResourceReference resourceReference)132     public abstract Builder setResourceReference(ResourceReference resourceReference);
133 
setDescription(String description)134     public abstract Builder setDescription(String description);
135 
136     // Private accessors.
name()137     abstract String name();
138 
originalName()139     abstract Optional<String> originalName();
140 
autoBuild()141     abstract Field autoBuild();
142 
build()143     public Field build() {
144       if (!originalName().isPresent()) {
145         setOriginalName(name());
146       }
147       return autoBuild();
148     }
149   }
150 }
151