Skip to content

Commit 0e9b46e

Browse files
authored
Handle Unions with "type" members (#6740)
1 parent 86ba462 commit 0e9b46e

7 files changed

Lines changed: 432 additions & 6 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"type": "bugfix",
3+
"category": "AWS SDK for Java v2",
4+
"contributor": "",
5+
"description": "Correctly handle unions with members named \"type\" by renaming the member variable to avoid conflicts with the existing SDK added \"type\" field."
6+
}

codegen/src/main/java/software/amazon/awssdk/codegen/AddShapes.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ private MemberModel generateMemberModel(String c2jMemberName, Member c2jMemberDe
158158
Map<String, Shape> allC2jShapes) {
159159
String c2jShapeName = c2jMemberDefinition.getShape();
160160
Shape shape = allC2jShapes.get(c2jShapeName);
161-
String variableName = getNamingStrategy().getVariableName(c2jMemberName);
161+
String variableName = getNamingStrategy().getVariableName(c2jMemberName, parentShape);
162162
String variableType = getTypeUtils().getJavaDataType(allC2jShapes, c2jShapeName);
163163
String variableDeclarationType = getTypeUtils().getJavaDataType(allC2jShapes, c2jShapeName);
164164

codegen/src/main/java/software/amazon/awssdk/codegen/naming/DefaultNamingStrategy.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,16 @@ public String getVariableName(String name) {
299299
return unCapitalize(name);
300300
}
301301

302+
@Override
303+
public String getVariableName(String name, Shape parentShape) {
304+
if (isJavaKeyword(name) ||
305+
isDisallowedNameForShape(unCapitalize(name), parentShape)) {
306+
return unCapitalize(name + CONFLICTING_NAME_SUFFIX);
307+
}
308+
309+
return unCapitalize(name);
310+
}
311+
302312
@Override
303313
public String getEnumValueName(String enumValue) {
304314
String result = enumValue;

codegen/src/main/java/software/amazon/awssdk/codegen/naming/NamingStrategy.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,13 @@ public interface NamingStrategy {
124124
*/
125125
String getVariableName(String name);
126126

127+
/**
128+
* @param name Some contextual name to derive variable name from (i.e. member name, java class name, etc).
129+
* @param parentShape The shape containing the member, used to check for shape-specific reserved names.
130+
* @return Appropriate name to use for a Java variable or field.
131+
*/
132+
String getVariableName(String name, Shape parentShape);
133+
127134
/**
128135
* @param enumValue Enum value as defined in the service model used to derive the java name.
129136
* @return Appropriate name to use for a Java enum value

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/operationwithreservedkeywordmemberrequest.java

Lines changed: 73 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,26 @@ public final class OperationWithReservedKeywordMemberRequest extends JsonProtoco
3535
.traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("ReservedKeywordMember").build())
3636
.build();
3737

38-
private static final List<SdkField<?>> SDK_FIELDS = Collections
39-
.unmodifiableList(Arrays.asList(RESERVED_KEYWORD_MEMBER_FIELD));
38+
private static final SdkField<UnionWithTypeMember> UNION_WITH_TYPE_MEMBER_FIELD = SdkField
39+
.<UnionWithTypeMember> builder(MarshallingType.SDK_POJO).memberName("UnionWithTypeMember")
40+
.getter(getter(OperationWithReservedKeywordMemberRequest::unionWithTypeMember))
41+
.setter(setter(Builder::unionWithTypeMember)).constructor(UnionWithTypeMember::builder)
42+
.traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("UnionWithTypeMember").build())
43+
.build();
44+
45+
private static final List<SdkField<?>> SDK_FIELDS = Collections.unmodifiableList(Arrays.asList(RESERVED_KEYWORD_MEMBER_FIELD,
46+
UNION_WITH_TYPE_MEMBER_FIELD));
4047

4148
private static final Map<String, SdkField<?>> SDK_NAME_TO_FIELD = memberNameToFieldInitializer();
4249

4350
private final ContainsReservedKeyword reservedKeywordMember;
4451

52+
private final UnionWithTypeMember unionWithTypeMember;
53+
4554
private OperationWithReservedKeywordMemberRequest(BuilderImpl builder) {
4655
super(builder);
4756
this.reservedKeywordMember = builder.reservedKeywordMember;
57+
this.unionWithTypeMember = builder.unionWithTypeMember;
4858
}
4959

5060
/**
@@ -56,6 +66,15 @@ public final ContainsReservedKeyword reservedKeywordMember() {
5666
return reservedKeywordMember;
5767
}
5868

69+
/**
70+
* Returns the value of the UnionWithTypeMember property for this object.
71+
*
72+
* @return The value of the UnionWithTypeMember property for this object.
73+
*/
74+
public final UnionWithTypeMember unionWithTypeMember() {
75+
return unionWithTypeMember;
76+
}
77+
5978
@Override
6079
public Builder toBuilder() {
6180
return new BuilderImpl(this);
@@ -74,6 +93,7 @@ public final int hashCode() {
7493
int hashCode = 1;
7594
hashCode = 31 * hashCode + super.hashCode();
7695
hashCode = 31 * hashCode + Objects.hashCode(reservedKeywordMember());
96+
hashCode = 31 * hashCode + Objects.hashCode(unionWithTypeMember());
7797
return hashCode;
7898
}
7999

@@ -94,7 +114,8 @@ public final boolean equalsBySdkFields(Object obj) {
94114
return false;
95115
}
96116
OperationWithReservedKeywordMemberRequest other = (OperationWithReservedKeywordMemberRequest) obj;
97-
return Objects.equals(reservedKeywordMember(), other.reservedKeywordMember());
117+
return Objects.equals(reservedKeywordMember(), other.reservedKeywordMember())
118+
&& Objects.equals(unionWithTypeMember(), other.unionWithTypeMember());
98119
}
99120

100121
/**
@@ -104,13 +125,15 @@ public final boolean equalsBySdkFields(Object obj) {
104125
@Override
105126
public final String toString() {
106127
return ToString.builder("OperationWithReservedKeywordMemberRequest")
107-
.add("ReservedKeywordMember", reservedKeywordMember()).build();
128+
.add("ReservedKeywordMember", reservedKeywordMember()).add("UnionWithTypeMember", unionWithTypeMember()).build();
108129
}
109130

110131
public final <T> Optional<T> getValueForField(String fieldName, Class<T> clazz) {
111132
switch (fieldName) {
112133
case "ReservedKeywordMember":
113134
return Optional.ofNullable(clazz.cast(reservedKeywordMember()));
135+
case "UnionWithTypeMember":
136+
return Optional.ofNullable(clazz.cast(unionWithTypeMember()));
114137
default:
115138
return Optional.empty();
116139
}
@@ -129,6 +152,7 @@ public final Map<String, SdkField<?>> sdkFieldNameToField() {
129152
private static Map<String, SdkField<?>> memberNameToFieldInitializer() {
130153
Map<String, SdkField<?>> map = new HashMap<>();
131154
map.put("ReservedKeywordMember", RESERVED_KEYWORD_MEMBER_FIELD);
155+
map.put("UnionWithTypeMember", UNION_WITH_TYPE_MEMBER_FIELD);
132156
return Collections.unmodifiableMap(map);
133157
}
134158

@@ -172,6 +196,34 @@ default Builder reservedKeywordMember(Consumer<ContainsReservedKeyword.Builder>
172196
return reservedKeywordMember(ContainsReservedKeyword.builder().applyMutation(reservedKeywordMember).build());
173197
}
174198

199+
/**
200+
* Sets the value of the UnionWithTypeMember property for this object.
201+
*
202+
* @param unionWithTypeMember
203+
* The new value for the UnionWithTypeMember property for this object.
204+
* @return Returns a reference to this object so that method calls can be chained together.
205+
*/
206+
Builder unionWithTypeMember(UnionWithTypeMember unionWithTypeMember);
207+
208+
/**
209+
* Sets the value of the UnionWithTypeMember property for this object.
210+
*
211+
* This is a convenience method that creates an instance of the {@link UnionWithTypeMember.Builder} avoiding the
212+
* need to create one manually via {@link UnionWithTypeMember#builder()}.
213+
*
214+
* <p>
215+
* When the {@link Consumer} completes, {@link UnionWithTypeMember.Builder#build()} is called immediately and
216+
* its result is passed to {@link #unionWithTypeMember(UnionWithTypeMember)}.
217+
*
218+
* @param unionWithTypeMember
219+
* a consumer that will call methods on {@link UnionWithTypeMember.Builder}
220+
* @return Returns a reference to this object so that method calls can be chained together.
221+
* @see #unionWithTypeMember(UnionWithTypeMember)
222+
*/
223+
default Builder unionWithTypeMember(Consumer<UnionWithTypeMember.Builder> unionWithTypeMember) {
224+
return unionWithTypeMember(UnionWithTypeMember.builder().applyMutation(unionWithTypeMember).build());
225+
}
226+
175227
@Override
176228
Builder overrideConfiguration(AwsRequestOverrideConfiguration overrideConfiguration);
177229

@@ -182,12 +234,15 @@ default Builder reservedKeywordMember(Consumer<ContainsReservedKeyword.Builder>
182234
static final class BuilderImpl extends JsonProtocolTestsRequest.BuilderImpl implements Builder {
183235
private ContainsReservedKeyword reservedKeywordMember;
184236

237+
private UnionWithTypeMember unionWithTypeMember;
238+
185239
private BuilderImpl() {
186240
}
187241

188242
private BuilderImpl(OperationWithReservedKeywordMemberRequest model) {
189243
super(model);
190244
reservedKeywordMember(model.reservedKeywordMember);
245+
unionWithTypeMember(model.unionWithTypeMember);
191246
}
192247

193248
public final ContainsReservedKeyword.Builder getReservedKeywordMember() {
@@ -204,6 +259,20 @@ public final Builder reservedKeywordMember(ContainsReservedKeyword reservedKeywo
204259
return this;
205260
}
206261

262+
public final UnionWithTypeMember.Builder getUnionWithTypeMember() {
263+
return unionWithTypeMember != null ? unionWithTypeMember.toBuilder() : null;
264+
}
265+
266+
public final void setUnionWithTypeMember(UnionWithTypeMember.BuilderImpl unionWithTypeMember) {
267+
this.unionWithTypeMember = unionWithTypeMember != null ? unionWithTypeMember.build() : null;
268+
}
269+
270+
@Override
271+
public final Builder unionWithTypeMember(UnionWithTypeMember unionWithTypeMember) {
272+
this.unionWithTypeMember = unionWithTypeMember;
273+
return this;
274+
}
275+
207276
@Override
208277
public Builder overrideConfiguration(AwsRequestOverrideConfiguration overrideConfiguration) {
209278
super.overrideConfiguration(overrideConfiguration);

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/service-2.json

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,18 @@
221221
"AllTypesUnionStructure":{"shape":"AllTypesUnionStructure"}
222222
}
223223
},
224+
"UnionWithTypeMember": {
225+
"type": "structure",
226+
"union": true,
227+
"members": {
228+
"StringMember": {
229+
"shape": "String"
230+
},
231+
"Type": {
232+
"shape": "String"
233+
}
234+
}
235+
},
224236
"BaseType":{
225237
"type":"structure",
226238
"members":{
@@ -278,7 +290,8 @@
278290
"members": {
279291
"ReservedKeywordMember": {
280292
"shape": "ContainsReservedKeyword"
281-
}
293+
},
294+
"UnionWithTypeMember": {"shape": "UnionWithTypeMember"}
282295
}
283296
},
284297
"Double":{"type":"double"},

0 commit comments

Comments
 (0)