@Override
  public Optional<ValueType> describe(
      PropertyPath path, TypeContext typeContext, DescribeContext context) {
    if (!applies(path, typeContext)) {
      return Optional.empty();
    }

    MappingResolver mappingResolver = context.getMappingResolver();
    Map<String, TypeDescriptor> typesByAlias = new LinkedHashMap<>();
    TypeDescriptor type = typeContext.type;
    String alias = Check.notNull(mappingResolver.alias(type).value, "alias");
    typesByAlias.put(alias, type);
    registerSubclasses(mappingResolver, typesByAlias, mappingResolver.subclasses(type));

    ObjectTypeMapping objectTypeMapping = new ObjectTypeMapping(typesByAlias);
    return objectTypeMapping.describe(path, typeContext, context);
  }
 private void registerSubclasses(
     MappingResolver mappingResolver,
     Map<String, TypeDescriptor> typesByAlias,
     Result<Map<TypeDescriptor, String>> subclasses) {
   if (subclasses.isPreset()) {
     for (Map.Entry<TypeDescriptor, String> entry : subclasses.value.entrySet()) {
       TypeDescriptor type = entry.getKey();
       String alias = entry.getValue();
       if (isNullOrEmpty(alias)) {
         alias = Check.notNull(mappingResolver.alias(type).value, "alias");
       }
       typesByAlias.put(alias, type);
     }
   }
 }