deserialize()

in packages/@jsii/kernel/src/serialization.ts [500:580]


    deserialize(value, optionalValue, host) {
      if (typeof value === 'object' && Object.keys(value ?? {}).length === 0) {
        // Treat empty structs as `undefined` (see https://github.com/aws/jsii/issues/411)
        value = undefined;
      }
      if (nullAndOk(value, optionalValue, host)) {
        return undefined;
      }
      assert(optionalValue !== VOID, 'Encountered unexpected void type!');

      if (typeof value !== 'object' || value == null) {
        throw new SerializationError(`Value is not an object`, value, host);
      }

      const namedType = host.lookupType(
        (optionalValue.type as spec.NamedTypeReference).fqn,
      );
      const props = propertiesOf(namedType, host.lookupType);

      if (Array.isArray(value)) {
        throw new SerializationError(
          'Value is an array (varargs may have been incorrectly supplied)',
          value,
          host,
        );
      }

      // Similarly to serialization, we might be getting a reference type where we're
      // expecting a value type. Accept this for now (but also validate that object
      // for presence of the right properties).
      if (isObjRef(value)) {
        host.debug(
          'Expected value type but got reference type, accepting for now (awslabs/jsii#400)',
        );

        // Return same INSTANCE (shouldn't matter but we don't know for sure that it doesn't)
        return validateRequiredProps(
          host.objects.findObject(value).instance,
          namedType.fqn,
          props,
          host,
        );
      }

      if (api.isWireStruct(value)) {
        const { fqn, data } = value[api.TOKEN_STRUCT];
        if (!isAssignable(fqn, namedType, host.lookupType)) {
          throw new SerializationError(
            `Wired struct has type '${fqn}', which does not match expected type`,
            value,
            host,
          );
        }
        value = data;
      }

      // Python, for example, allows using plain mapping objects instead of Structs (dyanmic typing, YOLO!)
      if (api.isWireMap(value)) {
        value = value[api.TOKEN_MAP];
      }

      value = validateRequiredProps(value as any, namedType.fqn, props, host);

      // Return a dict COPY, we have by-value semantics anyway.
      return mapValues(
        value,
        (v, key) => {
          if (!props[key]) {
            return undefined;
          } // Don't map if unknown property
          return process(
            host,
            'deserialize',
            v,
            props[key],
            `key ${inspect(key)}`,
          );
        },
        host,
      );
    },