Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: fix
packages:
- "@typespec/http-client-java"
---

Prevent duplicate Java fields and accessors when a model redeclares an inherited fixed discriminator.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public final class GoblinShark extends Shark {
* Discriminator property for Fish.
*/
@Metadata(properties = { MetadataProperties.GENERATED })
private String kind = "shark";
private final String kind = "shark";

/*
* The sharktype property.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public final class SawShark extends Shark {
* Discriminator property for Fish.
*/
@Metadata(properties = { MetadataProperties.GENERATED })
private String kind = "shark";
private final String kind = "shark";

/*
* The sharktype property.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class Shark extends Fish {
* Discriminator property for Fish.
*/
@Metadata(properties = { MetadataProperties.GENERATED })
private String kind = "shark";
private final String kind = "shark";

/*
* The sharktype property.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.microsoft.typespec.http.client.generator.core.model.javamodel.JavaFile;
import com.microsoft.typespec.http.client.generator.core.model.javamodel.JavaVisibility;
import com.microsoft.typespec.http.client.generator.core.util.ClientModelUtil;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;

Expand Down Expand Up @@ -116,7 +117,13 @@ private static void declareFieldInternal(ClientModelProperty discriminator, Clie
&& settings.isShareJsonSerializableCode()) {
classBlock.memberVariable(JavaVisibility.PackagePrivate, fieldSignature);
} else if (!allPolymorphicModelsInSamePackage || !settings.isShareJsonSerializableCode()) {
classBlock.privateMemberVariable(fieldSignature);
// Active discriminators stay mutable to preserve unknown values during fallback deserialization.
if (discriminator.isConstant()
&& !Objects.equals(discriminator.getSerializedName(), model.getPolymorphicDiscriminatorName())) {
classBlock.privateFinalMemberVariable(fieldSignature);
} else {
classBlock.privateMemberVariable(fieldSignature);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -363,11 +363,13 @@ public ClientModel map(ObjectSchema compositeType) {
// the correct serialization in multi-level polymorphic structures.
for (ClientModel derivedType : derivedTypes) {
if (!Objects.equals(polymorphicDiscriminator, derivedType.getPolymorphicDiscriminatorName())) {
// The child hierarchy stays in one fixed parent discriminator branch.
ClientModelProperty parentDiscriminator = result.getPolymorphicDiscriminator()
.newBuilder()
.defaultValue(result.getPolymorphicDiscriminator()
.getClientType()
.defaultValueExpression(derivedType.getSerializedName()))
.constant(true)
.build();

passPolymorphicDiscriminatorToChildren(parentDiscriminator, derivedType);
Expand All @@ -389,7 +391,33 @@ private static void passPolymorphicDiscriminatorToChildren(ClientModelProperty p
// discriminator kind, and model #3 is a child of model #3 with discriminator form. The order if this running
// will have model #2 add its discriminator to model #3 before model #1 runs adding its discriminator to #2 and
// #3. We want #3 to have the ordering of [type, kind], to represent the ordering of the parent models.
child.getParentPolymorphicDiscriminators().add(0, parentDiscriminator);
// Merge a matching child declaration to avoid emitting the inherited discriminator twice.
ClientModelProperty discriminatorForChild = parentDiscriminator;
for (int i = 0; i < child.getProperties().size(); i++) {
ClientModelProperty childProperty = child.getProperties().get(i);
if (!Objects.equals(parentDiscriminator.getSerializedName(), childProperty.getSerializedName())) {
continue;
}

if (!childProperty.isConstant()
|| !Objects.equals(parentDiscriminator.getWireType(), childProperty.getWireType())
|| !Objects.equals(parentDiscriminator.getClientType(), childProperty.getClientType())
|| !Objects.equals(parentDiscriminator.getDefaultValue(), childProperty.getDefaultValue())) {
throw new IllegalStateException("Property '" + childProperty.getSerializedName() + "' on model '"
+ child.getName() + "' does not match its inherited polymorphic discriminator.");
}

discriminatorForChild = childProperty.newBuilder()
.name(parentDiscriminator.getName())
.readOnly(true)
.required(false)
.polymorphicDiscriminator(true)
.build();
child.getProperties().remove(i);
break;
}

child.getParentPolymorphicDiscriminators().add(0, discriminatorForChild);

for (ClientModel derived : child.getDerivedModels()) {
passPolymorphicDiscriminatorToChildren(parentDiscriminator, derived);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public final class GoblinShark extends Shark {
/*
* Discriminator property for Fish.
*/
private String kind = "shark";
private final String kind = "shark";

/*
* The sharktype property.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public final class SawShark extends Shark {
/*
* Discriminator property for Fish.
*/
private String kind = "shark";
private final String kind = "shark";

/*
* The sharktype property.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class Shark extends FishInner {
/*
* Discriminator property for Fish.
*/
private String kind = "shark";
private final String kind = "shark";

/*
* The sharktype property.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public final class GoblinShark extends Shark {
* discriminator property
*/
@Generated
private FishKind kind = FishKind.SHARK;
private final FishKind kind = FishKind.SHARK;

/*
* The sharktype property.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
@Immutable
public final class SawShark extends Shark {
/*
* discriminator property
* The kind property.
*/
@Generated
private FishKind kind = FishKind.SHARK;
private final FishKind kind = FishKind.SHARK;

/*
* The sharktype property.
Expand All @@ -39,7 +39,7 @@ public SawShark(int age) {
}

/**
* Get the kind property: discriminator property.
* Get the kind property: The kind property.
*
* @return the kind value.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class Shark extends Fish {
* discriminator property
*/
@Generated
private FishKind kind = FishKind.SHARK;
private final FishKind kind = FishKind.SHARK;

/*
* The sharktype property.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public final class SawShark extends Shark {
* Discriminator property for Fish.
*/
@Generated
private String kind = "shark";
private final String kind = "shark";

/*
* The sharktype property.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class Shark extends Fish {
* Discriminator property for Fish.
*/
@Generated
private String kind = "shark";
private final String kind = "shark";

/*
* The sharktype property.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public final class GoblinShark extends Shark {
* Discriminator property for Fish.
*/
@Generated
private String kind = "shark";
private final String kind = "shark";

/*
* The sharktype property.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public final class SawShark extends Shark {
* Discriminator property for Fish.
*/
@Generated
private String kind = "shark";
private final String kind = "shark";

/*
* The sharktype property.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class Shark extends Fish {
* Discriminator property for Fish.
*/
@Generated
private String kind = "shark";
private final String kind = "shark";

/*
* The sharktype property.
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"flavor":"Azure","apiVersions":{},"crossLanguagePackageId":"TspTest.EnumNestedDiscriminator","crossLanguageVersion":"a7268a26bdc4","crossLanguageDefinitions":{"tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorAsyncClient":"TspTest.EnumNestedDiscriminator","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorAsyncClient.getMissingDiscriminator":"TspTest.EnumNestedDiscriminator.getMissingDiscriminator","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorAsyncClient.getMissingDiscriminatorWithResponse":"TspTest.EnumNestedDiscriminator.getMissingDiscriminator","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorAsyncClient.getModel":"TspTest.EnumNestedDiscriminator.getModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorAsyncClient.getModelWithResponse":"TspTest.EnumNestedDiscriminator.getModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorAsyncClient.getRecursiveModel":"TspTest.EnumNestedDiscriminator.getRecursiveModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorAsyncClient.getRecursiveModelWithResponse":"TspTest.EnumNestedDiscriminator.getRecursiveModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorAsyncClient.getWrongDiscriminator":"TspTest.EnumNestedDiscriminator.getWrongDiscriminator","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorAsyncClient.getWrongDiscriminatorWithResponse":"TspTest.EnumNestedDiscriminator.getWrongDiscriminator","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorAsyncClient.putModel":"TspTest.EnumNestedDiscriminator.putModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorAsyncClient.putModelWithResponse":"TspTest.EnumNestedDiscriminator.putModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorAsyncClient.putRecursiveModel":"TspTest.EnumNestedDiscriminator.putRecursiveModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorAsyncClient.putRecursiveModelWithResponse":"TspTest.EnumNestedDiscriminator.putRecursiveModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClient":"TspTest.EnumNestedDiscriminator","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClient.getMissingDiscriminator":"TspTest.EnumNestedDiscriminator.getMissingDiscriminator","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClient.getMissingDiscriminatorWithResponse":"TspTest.EnumNestedDiscriminator.getMissingDiscriminator","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClient.getModel":"TspTest.EnumNestedDiscriminator.getModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClient.getModelWithResponse":"TspTest.EnumNestedDiscriminator.getModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClient.getRecursiveModel":"TspTest.EnumNestedDiscriminator.getRecursiveModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClient.getRecursiveModelWithResponse":"TspTest.EnumNestedDiscriminator.getRecursiveModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClient.getWrongDiscriminator":"TspTest.EnumNestedDiscriminator.getWrongDiscriminator","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClient.getWrongDiscriminatorWithResponse":"TspTest.EnumNestedDiscriminator.getWrongDiscriminator","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClient.putModel":"TspTest.EnumNestedDiscriminator.putModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClient.putModelWithResponse":"TspTest.EnumNestedDiscriminator.putModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClient.putRecursiveModel":"TspTest.EnumNestedDiscriminator.putRecursiveModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClient.putRecursiveModelWithResponse":"TspTest.EnumNestedDiscriminator.putRecursiveModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClientBuilder":"TspTest.EnumNestedDiscriminator","tsptest.enumnesteddiscriminator.models.Fish":"TspTest.EnumNestedDiscriminator.Fish","tsptest.enumnesteddiscriminator.models.FishKind":"TspTest.EnumNestedDiscriminator.FishKind","tsptest.enumnesteddiscriminator.models.GoblinShark":"TspTest.EnumNestedDiscriminator.GoblinShark","tsptest.enumnesteddiscriminator.models.Salmon":"TspTest.EnumNestedDiscriminator.Salmon","tsptest.enumnesteddiscriminator.models.SawShark":"TspTest.EnumNestedDiscriminator.SawShark","tsptest.enumnesteddiscriminator.models.Shark":"TspTest.EnumNestedDiscriminator.Shark","tsptest.enumnesteddiscriminator.models.SharkKind":"TspTest.EnumNestedDiscriminator.SharkKind"},"generatedFiles":["src/main/java/module-info.java","src/main/java/tsptest/enumnesteddiscriminator/EnumNestedDiscriminatorAsyncClient.java","src/main/java/tsptest/enumnesteddiscriminator/EnumNestedDiscriminatorClient.java","src/main/java/tsptest/enumnesteddiscriminator/EnumNestedDiscriminatorClientBuilder.java","src/main/java/tsptest/enumnesteddiscriminator/implementation/EnumNestedDiscriminatorClientImpl.java","src/main/java/tsptest/enumnesteddiscriminator/implementation/package-info.java","src/main/java/tsptest/enumnesteddiscriminator/models/Fish.java","src/main/java/tsptest/enumnesteddiscriminator/models/FishKind.java","src/main/java/tsptest/enumnesteddiscriminator/models/GoblinShark.java","src/main/java/tsptest/enumnesteddiscriminator/models/Salmon.java","src/main/java/tsptest/enumnesteddiscriminator/models/SawShark.java","src/main/java/tsptest/enumnesteddiscriminator/models/Shark.java","src/main/java/tsptest/enumnesteddiscriminator/models/SharkKind.java","src/main/java/tsptest/enumnesteddiscriminator/models/package-info.java","src/main/java/tsptest/enumnesteddiscriminator/package-info.java"]}
{"flavor":"Azure","apiVersions":{},"crossLanguagePackageId":"TspTest.EnumNestedDiscriminator","crossLanguageVersion":"e2c89125d0a8","crossLanguageDefinitions":{"tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorAsyncClient":"TspTest.EnumNestedDiscriminator","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorAsyncClient.getMissingDiscriminator":"TspTest.EnumNestedDiscriminator.getMissingDiscriminator","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorAsyncClient.getMissingDiscriminatorWithResponse":"TspTest.EnumNestedDiscriminator.getMissingDiscriminator","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorAsyncClient.getModel":"TspTest.EnumNestedDiscriminator.getModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorAsyncClient.getModelWithResponse":"TspTest.EnumNestedDiscriminator.getModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorAsyncClient.getRecursiveModel":"TspTest.EnumNestedDiscriminator.getRecursiveModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorAsyncClient.getRecursiveModelWithResponse":"TspTest.EnumNestedDiscriminator.getRecursiveModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorAsyncClient.getWrongDiscriminator":"TspTest.EnumNestedDiscriminator.getWrongDiscriminator","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorAsyncClient.getWrongDiscriminatorWithResponse":"TspTest.EnumNestedDiscriminator.getWrongDiscriminator","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorAsyncClient.putModel":"TspTest.EnumNestedDiscriminator.putModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorAsyncClient.putModelWithResponse":"TspTest.EnumNestedDiscriminator.putModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorAsyncClient.putRecursiveModel":"TspTest.EnumNestedDiscriminator.putRecursiveModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorAsyncClient.putRecursiveModelWithResponse":"TspTest.EnumNestedDiscriminator.putRecursiveModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClient":"TspTest.EnumNestedDiscriminator","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClient.getMissingDiscriminator":"TspTest.EnumNestedDiscriminator.getMissingDiscriminator","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClient.getMissingDiscriminatorWithResponse":"TspTest.EnumNestedDiscriminator.getMissingDiscriminator","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClient.getModel":"TspTest.EnumNestedDiscriminator.getModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClient.getModelWithResponse":"TspTest.EnumNestedDiscriminator.getModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClient.getRecursiveModel":"TspTest.EnumNestedDiscriminator.getRecursiveModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClient.getRecursiveModelWithResponse":"TspTest.EnumNestedDiscriminator.getRecursiveModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClient.getWrongDiscriminator":"TspTest.EnumNestedDiscriminator.getWrongDiscriminator","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClient.getWrongDiscriminatorWithResponse":"TspTest.EnumNestedDiscriminator.getWrongDiscriminator","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClient.putModel":"TspTest.EnumNestedDiscriminator.putModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClient.putModelWithResponse":"TspTest.EnumNestedDiscriminator.putModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClient.putRecursiveModel":"TspTest.EnumNestedDiscriminator.putRecursiveModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClient.putRecursiveModelWithResponse":"TspTest.EnumNestedDiscriminator.putRecursiveModel","tsptest.enumnesteddiscriminator.EnumNestedDiscriminatorClientBuilder":"TspTest.EnumNestedDiscriminator","tsptest.enumnesteddiscriminator.models.Fish":"TspTest.EnumNestedDiscriminator.Fish","tsptest.enumnesteddiscriminator.models.FishKind":"TspTest.EnumNestedDiscriminator.FishKind","tsptest.enumnesteddiscriminator.models.GoblinShark":"TspTest.EnumNestedDiscriminator.GoblinShark","tsptest.enumnesteddiscriminator.models.Salmon":"TspTest.EnumNestedDiscriminator.Salmon","tsptest.enumnesteddiscriminator.models.SawShark":"TspTest.EnumNestedDiscriminator.SawShark","tsptest.enumnesteddiscriminator.models.Shark":"TspTest.EnumNestedDiscriminator.Shark","tsptest.enumnesteddiscriminator.models.SharkKind":"TspTest.EnumNestedDiscriminator.SharkKind"},"generatedFiles":["src/main/java/module-info.java","src/main/java/tsptest/enumnesteddiscriminator/EnumNestedDiscriminatorAsyncClient.java","src/main/java/tsptest/enumnesteddiscriminator/EnumNestedDiscriminatorClient.java","src/main/java/tsptest/enumnesteddiscriminator/EnumNestedDiscriminatorClientBuilder.java","src/main/java/tsptest/enumnesteddiscriminator/implementation/EnumNestedDiscriminatorClientImpl.java","src/main/java/tsptest/enumnesteddiscriminator/implementation/package-info.java","src/main/java/tsptest/enumnesteddiscriminator/models/Fish.java","src/main/java/tsptest/enumnesteddiscriminator/models/FishKind.java","src/main/java/tsptest/enumnesteddiscriminator/models/GoblinShark.java","src/main/java/tsptest/enumnesteddiscriminator/models/Salmon.java","src/main/java/tsptest/enumnesteddiscriminator/models/SawShark.java","src/main/java/tsptest/enumnesteddiscriminator/models/Shark.java","src/main/java/tsptest/enumnesteddiscriminator/models/SharkKind.java","src/main/java/tsptest/enumnesteddiscriminator/models/package-info.java","src/main/java/tsptest/enumnesteddiscriminator/package-info.java"]}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ model Salmon extends Fish {

@doc("The third level model SawShark in polymorphic multiple levels inheritance.")
model SawShark extends Shark {
kind: FishKind.Shark;
sharktype: SharkKind.Saw;
}

Expand Down