/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow strict
 * @format
 */

'use strict';

import type {ObjectTypeAliasTypeShape} from '../../CodegenSchema';

function getTypeAliasTypeAnnotation(
  name: string,
  aliases: $ReadOnly<{[aliasName: string]: ObjectTypeAliasTypeShape, ...}>,
): $ReadOnly<ObjectTypeAliasTypeShape> {
  const typeAnnotation = aliases[name];
  if (!typeAnnotation) {
    throw Error(`No type annotation found for "${name}" in schema`);
  }
  if (typeAnnotation.type === 'ObjectTypeAnnotation') {
    if (typeAnnotation.properties) {
      return typeAnnotation;
    }

    throw new Error(
      `Unsupported type for "${name}". Please provide properties.`,
    );
  }
  // $FlowFixMe[incompatible-type]
  if (typeAnnotation.type === 'TypeAliasTypeAnnotation') {
    return getTypeAliasTypeAnnotation(typeAnnotation.name, aliases);
  }

  throw Error(
    `Unsupported type annotation in alias "${name}", found: ${typeAnnotation.type}`,
  );
}

module.exports = {
  getTypeAliasTypeAnnotation,
};

@@ -245,241 +245,412 @@
 pe %7B
-ObjectTypeAliasTypeShape%7D from '../../CodegenSchema';%0A%0Afunction getT
+%0A  SchemaType,%0A  NativeModuleAliasMap,%0A  Required,%0A  NativeModuleObjectTypeAnnotation,%0A  NativeModuleSchema,%0A%7D from '../../CodegenSchema';%0A%0Aconst invariant = require('invariant');%0A%0Aexport t
 ype
+ 
 Alias
-TypeAnnotation(%0A  name: string,%0A  aliases: $ReadOnly%3C%7B%5BaliasName: string%5D: ObjectTypeAliasTypeShape, ...%7D%3E,%0A): $ReadOnly%3CObjectTypeAliasTypeShape
+Resolver = (%0A  aliasName: string,%0A) =%3E Required%3CNativeModuleObjectTypeAnnotation%3E;%0A%0Afunction createAliasResolver(aliasMap: NativeModuleAliasMap): AliasResolver %7B%0A  return (aliasName: string) =
 %3E %7B%0A
+  
   const 
 type
@@ -649,690 +649,583 @@
 nst 
-typeAnnotation = aliases%5Bname%5D;%0A  if (!typeAnnotation) %7B%0A    throw Error(%60No type annotation found for %22$%7Bname%7D%22 in schema%60);%0A  %7D%0A  if (typeAnnotation.type === 'ObjectTypeAnnotation') %7B%0A    if (typeAnnotation.properties) %7B%0A      return typeAnnotation;%0A    %7D%0A%0A    throw new Error(%0A      %60Unsupported type for %22$%7Bname%7D%22. Please provide properties.%60
+alias = aliasMap%5BaliasName%5D;%0A    invariant(alias != null, %60Unable to resolve type alias '$%7BaliasName%7D'.%60);%0A    return alias;%0A  %7D;%0A%7D%0A%0Afunction getModules(%0A  schema: SchemaType,%0A): $ReadOnly%3C%7B%7C%5BmoduleName: string%5D: NativeModuleSchema%7C%7D%3E %7B%0A  return Object.keys(schema.modules)%0A    .map%3C?%7B+%5Bstring%5D: NativeModuleSchema%7D%3E(%0A      moduleName =%3E schema.modules%5BmoduleName%5D.nativeModules
 ,%0A    )
-;
 %0A  
-%7D%0A  // $FlowFixMe%5Bincompatible-type%5D%0A  if (typeAnnotation.type === 'TypeAliasTypeAnnotation') %7B
+  .filter(Boolean)
 %0A    
+.
 re
-turn getTypeAliasTypeAnnotation(typeAnnotation.name, aliases);%0A  %7D%0A%0A  throw Error(%0A    %60Unsupported type annotation in alias %22$%7Bname%7D%22, found: $%7BtypeAnnotation.type%7D%60,%0A  );%0A%7D%0A%0Amodule.exports = %7B%0A  getTypeAliasTypeAnnotation
+duce%3C%7B+%5Bstring%5D: NativeModuleSchema%7D%3E(%0A      (acc, modules) =%3E (%7B...acc, ...modules%7D),%0A      %7B%7D,%0A    );%0A%7D%0A%0Amodule.exports = %7B%0A  createAliasResolver,%0A  getModules
 ,%0A%7D;

Create utilities for module generators