/**
 * Copyright (c) 2016-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */ import * as AlgebraicType from './algebraic-type' ; import * as Code from './code' ; import * as Either from './either' ; import * as Error from './error' ; import * as FileWriter from './file-writer' ; import * as List from './list' ; import * as Maybe from './maybe' ; import * as ObjC from './objc' ; import * as PluggableObjCFileCreation from './pluggable-objc-file-creation' ; export interface Request extends PluggableObjCFileCreation . ObjCGenerationRequest < AlgebraicType . Type > { } interface AlgebraicTypeObjCPlugIn extends PluggableObjCFileCreation . ObjCGenerationPlugIn < AlgebraicType . Type > { } function createAlgebraicTypeObjCPlugIn ( plugin ) { return { additionalFiles : function ( typeInformation ) : Code . File [ ] { return plugin . additionalFiles ( typeInformation ) ; } , transformBaseFile : function ( typeInformation , baseFile ) : Code . File { return plugin . transformBaseFile ( typeInformation , baseFile ) ; } , baseClass : plugin . baseClass != null ? plugin . baseClass : ( _ ) => null , blockTypes : function ( typeInformation ) : ObjC . BlockType [ ] { return plugin . blockTypes ( typeInformation ) ; } , classMethods : function ( typeInformation ) : ObjC . Method [ ] { return plugin . classMethods ( typeInformation ) ; } , comments : function ( typeInformation ) : ObjC . Comment [ ] { return plugin . headerComments ( typeInformation ) ; } , enumerations : function ( typeInformation ) : ObjC . Enumeration [ ] { return plugin . enumerations ( typeInformation ) ; } , transformFileRequest : function ( writeRequest ) : FileWriter . Request { return plugin . transformFileRequest ( writeRequest ) ; } , fileType : function ( typeInformation ) : Code . FileType | null { return plugin . fileType ( typeInformation ) ; } , forwardDeclarations : function ( typeInformation ) : ObjC . ForwardDeclaration [ ] { return plugin . forwardDeclarations ( typeInformation ) ; } , functions : function ( typeInformation ) : ObjC . Function [ ] { return plugin . functions ( typeInformation ) ; } , implementedProtocols : function ( typeInformation ) : ObjC . ImplementedProtocol [ ] { return plugin . implementedProtocols ( typeInformation ) ; } , imports : function ( typeInformation ) : ObjC . Import [ ] { return plugin . imports ( typeInformation ) ; } , instanceVariables : function ( typeInformation ) : ObjC . InstanceVariable [ ] { return plugin . instanceVariables ( typeInformation ) ; } , instanceMethods : function ( typeInformation ) : ObjC . Method [ ] { return plugin . instanceMethods ( typeInformation ) ; } , structs : function ( typeInformation ) : Code . Struct [ ] { return plugin . structs != null ? plugin . structs ( typeInformation ) : [ ] ; } , macros : plugin . macros , properties : function ( typeInformation ) : ObjC . Property [ ] { return [ ] ; } , protocols : function ( typeInformation ) : ObjC . Protocol [ ] { return [ ] ; } , staticConstants : function ( typeInformation ) : ObjC . Constant [ ] { return plugin . staticConstants ( typeInformation ) ; } , globalVariables : function ( typeInformation ) : ObjC . GlobalVariable [ ] { return plugin . globalVariables ? plugin . globalVariables ( typeInformation ) : [ ] ; } , validationErrors : function ( typeInformation ) : Error . Error [ ] { return plugin . validationErrors ( typeInformation ) ; } , nullability : function ( typeInformation ) : ObjC . ClassNullability | null { return plugin . nullability ( typeInformation ) ; } , subclassingRestricted : function ( typeInformation ) : boolean { return plugin . subclassingRestricted ( typeInformation ) ; } , requiredIncludesToRun : plugin . requiredIncludesToRun } ; } function shouldRunPluginForInclude ( includes , requiredIncludeToRun ) { return includes . indexOf ( requiredIncludeToRun ) !== - 1 ; } function shouldRunPluginForIncludes ( includes , plugin ) { return plugin . requiredIncludesToRun . every ( ( include ) => shouldRunPluginForInclude ( includes , include ) ) ; } function pluginsToRunForAlgebraicType ( plugins , algebraicType ) { return List . filter ( ( plugin ) => shouldRunPluginForIncludes ( algebraicType . includes , plugin ) , plugins ) ; } function typeNameForType ( typeInformation ) { return typeInformation . name ; } function commentsForType ( typeInformation ) { return typeInformation . comments ; } function visibilityForType ( typeInformation ) { var visibility = undefined ; for ( const key in typeInformation . annotations ) { if ( key === 'visibility' ) { const len = typeInformation . annotations [ key ] . length ; if ( len > 0 ) { const lastValue = typeInformation . annotations [ key ] [ len - 1 ] . properties [ 'value' ] ; if ( lastValue === 'default' ) { visibility = ObjC . ClassVisibility . default ; } else if ( lastValue === 'hidden' ) { visibility = ObjC . ClassVisibility . hidden ; } } } } return visibility ; } export function fileWriteRequest ( request , plugins ) { const pluginsToRun = pluginsToRunForAlgebraicType ( plugins , request . typeInformation ) ; const wrappedPlugins = List . map ( createAlgebraicTypeObjCPlugIn , pluginsToRun ) ; const typeInfoProvider = { additionalTypesForType : function ( typeInformation ) { return [ ] ; } , typeNameForType : typeNameForType , commentsForType : commentsForType , visibilityForType : visibilityForType } ; return PluggableObjCFileCreation . fileWriteRequest ( request , typeInfoProvider , wrappedPlugins ) ; }