code: public void prepare(String sql, int connectionFlags, CancellationSignal cancellationSignal,
              SQLiteStatementInfo outStatementInfo) {
          if (sql == null) {
              throw new IllegalArgumentException("sql must not be null.");
          }
  
          if (cancellationSignal != null) {
              cancellationSignal.throwIfCanceled();
          }
  
          acquireConnection(sql, connectionFlags, cancellationSignal); // might throw
          try {
              mConnection.prepare(sql, outStatementInfo); // might throw
          } finally {
              releaseConnection(); // might throw
          }
      }
docs: Prepares a statement for execution but does not bind its parameters or execute it.
  <p>
  This method can be used to check for syntax errors during compilation
  prior to execution of the statement.  If the {@code outStatementInfo} argument
  is not null, the provided {@link SQLiteStatementInfo} object is populated
  with information about the statement.
  </p><p>
  A prepared statement makes no reference to the arguments that may eventually
  be bound to it, consequently it it possible to cache certain prepared statements
  such as SELECT or INSERT/UPDATE statements.  If the statement is cacheable,
  then it will be stored in the cache for later and reused if possible.
  </p>
  
  @param sql The SQL statement to prepare.
  @param connectionFlags The connection flags to use if a connection must be
  acquired by this operation.  Refer to {@link SQLiteConnectionPool}.
  @param cancellationSignal A signal to cancel the operation in progress, or null if none.
  @param outStatementInfo The {@link SQLiteStatementInfo} object to populate
  with information about the statement, or null if none.
  
  @throws SQLiteException if an error occurs, such as a syntax error.
  @throws OperationCanceledException if the operation was canceled.