text: /**
   * Copyright (c) 2015-present, Facebook, Inc.
   * All rights reserved.
   *
   * This source code is licensed under the BSD-style license found in the
   * LICENSE file in the root directory of this source tree. An additional grant
   * of patent rights can be found in the PATENTS file in the same directory.
   */
  
  #import <Foundation/Foundation.h>
  
  #import "RCTDefines.h"
  
  /**
   * RCTProfile
   *
   * This file provides a set of functions and macros for performance profiling
   *
   * NOTE: This API is a work in a work in progress, please consider carefully
   * before before using it.
   */
  
  RCT_EXTERN NSString *const RCTProfileDidStartProfiling;
  RCT_EXTERN NSString *const RCTProfileDidEndProfiling;
  
  #if RCT_DEV
  
  @class RCTBridge;
  
  #define RCTProfileBeginFlowEvent() \
  _Pragma("clang diagnostic push") \
  _Pragma("clang diagnostic ignored \"-Wshadow\"") \
  NSNumber *__rct_profile_flow_id = _RCTProfileBeginFlowEvent(); \
  _Pragma("clang diagnostic pop")
  
  #define RCTProfileEndFlowEvent() \
  _RCTProfileEndFlowEvent(__rct_profile_flow_id)
  
  RCT_EXTERN NSNumber *_RCTProfileBeginFlowEvent(void);
  RCT_EXTERN void _RCTProfileEndFlowEvent(NSNumber *);
  
  /**
   * Returns YES if the profiling information is currently being collected
   */
  RCT_EXTERN BOOL RCTProfileIsProfiling(void);
  
  /**
   * Start collecting profiling information
   */
  RCT_EXTERN void RCTProfileInit(RCTBridge *);
  
  /**
   * Stop profiling and return a JSON string of the collected data - The data
   * returned is compliant with google's trace event format - the format used
   * as input to trace-viewer
   */
  RCT_EXTERN NSString *RCTProfileEnd(RCTBridge *);
  
  /**
   * Collects the initial event information for the event and returns a reference ID
   */
  RCT_EXTERN void RCTProfileBeginEvent(uint64_t tag,
                                       NSString *name,
                                       NSDictionary *args);
  
  /**
   * The ID returned by BeginEvent should then be passed into EndEvent, with the
   * rest of the event information. Just at this point the event will actually be
   * registered
   */
  RCT_EXTERN void RCTProfileEndEvent(uint64_t tag,
                                     NSString *category,
                                     NSDictionary *args);
  
  /**
   * Collects the initial event information for the event and returns a reference ID
   */
  RCT_EXTERN int RCTProfileBeginAsyncEvent(uint64_t tag,
                                           NSString *name,
                                           NSDictionary *args);
  
  /**
   * The ID returned by BeginEvent should then be passed into EndEvent, with the
   * rest of the event information. Just at this point the event will actually be
   * registered
   */
  RCT_EXTERN void RCTProfileEndAsyncEvent(uint64_t tag,
                                          NSString *category,
                                          int cookie,
                                          NSString *name,
                                          NSDictionary *args);
  /**
   * An event that doesn't have a duration (i.e. Notification, VSync, etc)
   */
  RCT_EXTERN void RCTProfileImmediateEvent(uint64_t tag,
                                           NSString *name,
                                           char scope);
  
  /**
   * Helper to profile the duration of the execution of a block. This method uses
   * self and _cmd to name this event for simplicity sake.
   *
   * NOTE: The block can't expect any argument
   */
  #define RCTProfileBlock(block, tag, category, arguments) \
  ^{ \
    RCTProfileBeginEvent(tag, @(__PRETTY_FUNCTION__), nil); \
    block(); \
    RCTProfileEndEvent(tag, category, arguments); \
  }
  
  /**
   * Hook into a bridge instance to log all bridge module's method calls
   */
  RCT_EXTERN void RCTProfileHookModules(RCTBridge *);
  
  /**
   * Unhook from a given bridge instance's modules
   */
  RCT_EXTERN void RCTProfileUnhookModules(RCTBridge *);
  
  /**
   * Send systrace or cpu profiling information to the packager
   * to present to the user
   */
  RCT_EXTERN void RCTProfileSendResult(RCTBridge *bridge, NSString *route, NSData *profielData);
  
  /**
   * Systrace gluecode
   *
   * allow to use systrace to back RCTProfile
   */
  
  typedef struct {
    const char *key;
    int key_len;
    const char *value;
    int value_len;
  } systrace_arg_t;
  
  typedef struct {
    void (*start)(uint64_t enabledTags, char *buffer, size_t bufferSize);
    void (*stop)(void);
  
    void (*begin_section)(uint64_t tag, const char *name, size_t numArgs, systrace_arg_t *args);
    void (*end_section)(uint64_t tag, size_t numArgs, systrace_arg_t *args);
  
    void (*begin_async_section)(uint64_t tag, const char *name, int cookie, size_t numArgs, systrace_arg_t *args);
    void (*end_async_section)(uint64_t tag, const char *name, int cookie, size_t numArgs, systrace_arg_t *args);
  
    void (*instant_section)(uint64_t tag, const char *name, char scope);
  } RCTProfileCallbacks;
  
  RCT_EXTERN void RCTProfileRegisterCallbacks(RCTProfileCallbacks *);
  
  #else
  
  #define RCTProfileBeginFlowEvent()
  #define _RCTProfileBeginFlowEvent() @0
  
  #define RCTProfileEndFlowEvent()
  #define _RCTProfileEndFlowEvent()
  
  #define RCTProfileIsProfiling(...) NO
  #define RCTProfileInit(...)
  #define RCTProfileEnd(...) @""
  
  #define RCTProfileBeginEvent(...)
  #define RCTProfileEndEvent(...)
  
  #define RCTProfileBeginAsyncEvent(...) 0
  #define RCTProfileEndAsyncEvent(...)
  
  #define RCTProfileImmediateEvent(...)
  
  #define RCTProfileBlock(block, ...) block
  
  #define RCTProfileHookModules(...)
  #define RCTProfileUnhookModules(...)
  
  #define RCTProfileSendResult(...)
  
  #endif
  