I don't think the parse() function needs to have the Document parameter because you can get to a Document/Email from a Stream. You just need to check if the stream was attached to Document or Email.
The alternative would be to have a separate parseDocument(Document $document) and parseEmail(Email $email). I think this approach is closer to your design where you have separate tables for Document and Email.
If you want to do processing based on Stream like in your example, I think the database design can be made clearer by removing the Documents and Emails tables and put the text inside Streams and add a DocumentData to keep your Documents name and path. This way, the code doesn't need to care about the distinction, except when it needs to save/send which can be looked up quickly through a foreign key to DocumentData.