in packages/jsii-pacmak/lib/targets/java.ts [1782:1870]
function validateTypeUnion(
this: JavaGenerator,
value: string,
descr: string,
type: spec.UnionTypeReference,
parameterName: string,
) {
let emitAnd = false;
const nestedCollectionUnionTypes = new Map<string, spec.TypeReference>();
const typeRefs = type.union.types;
if (typeRefs.length > 1) {
this.code.indent('if (');
}
const checked = new Set<string>();
for (const typeRef of typeRefs) {
const prefix = emitAnd ? '&&' : '';
const javaRawType = this.toJavaTypeNoGenerics(typeRef);
if (checked.has(javaRawType)) {
continue;
} else {
checked.add(javaRawType);
}
const javaType = this.toJavaType(typeRef);
if (javaRawType !== javaType) {
nestedCollectionUnionTypes.set(javaType, typeRef);
}
const test = `${value} instanceof ${javaRawType}`;
if (typeRefs.length > 1) {
this.code.line(`${prefix} !(${test})`);
}
emitAnd = true;
}
if (
typeRefs.length > 1 &&
typeRefs.some(
(t) =>
spec.isNamedTypeReference(t) &&
spec.isInterfaceType(this.findType(t.fqn)),
)
) {
// Only anonymous objects at runtime can be `JsiiObject`s.
this.code.line(
`&& !(${value}.getClass().equals(software.amazon.jsii.JsiiObject.class))`,
);
}
if (typeRefs.length > 1) {
this.code.unindent(false);
this.code.openBlock(')');
const placeholders = typeRefs
.map((typeRef) => {
return `${this.toJavaType(typeRef)}`;
})
.join(', ');
this.code.indent(`throw new IllegalArgumentException(`);
this.code.indent(`new java.lang.StringBuilder("Expected ")`);
this.code.line(descr);
this.code.line(`.append(" to be one of: ${placeholders}; received ")`);
this.code.line(`.append(${value}.getClass()).toString());`);
this.code.unindent(false);
this.code.unindent(false);
this.code.closeBlock();
}
for (const [javaType, typeRef] of nestedCollectionUnionTypes) {
const varName =
typeRefs.length > 1
? `__cast_${createHash('sha256')
.update(value)
.digest('hex')
.slice(0, 6)}`
: value;
if (typeRefs.length > 1) {
this.code.openBlock(
`if (${value} instanceof ${this.toJavaTypeNoGenerics(typeRef)})`,
);
this.code.line(`@SuppressWarnings("unchecked")`);
this.code.line(
`final ${javaType} ${varName} = (${javaType})${value};`,
);
}
validate.call(this, varName, descr, typeRef, parameterName);
if (typeRefs.length > 1) {
this.code.closeBlock();
}
}
}