function validateTypeUnion()

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();
        }
      }
    }