Action hook save_post for newly created posts – $post object data is all empty

The first time that save_post fires it is when WordPress is creating an auto draft. See Why does save_post action fire when creating a new post?

To fix, just check to see if the passed $post variable has a post status of auto-draft.

add_action( 'save_post', 'my_save_post', 10, 3 );
function my_save_post( $post_id, $post, $update ) {
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
    if( 'auto-draft' === $post->post_status ) return;
    $pdf = new PDF();
    $pdf->createPDF( $post );
}