docs: def reader_trampoline(start, allow_flush=False):
      """Provides the co-routine trampoline for a reader state machine.
  
      The given co-routine is a state machine that yields :class:`Transition` and takes
      a Transition of :class:`amazon.ion.core.DataEvent` and the co-routine itself.
  
      A reader must start with a ``ReadEventType.NEXT`` event to prime the parser.  In many cases
      this will lead to an ``IonEventType.INCOMPLETE`` being yielded, but not always
      (consider a reader over an in-memory data structure).
  
      Notes:
          A reader delimits its incomplete parse points with ``IonEventType.INCOMPLETE``.
          Readers also delimit complete parse points with ``IonEventType.STREAM_END``;
          this is similar to the ``INCOMPLETE`` case except that it denotes that a logical
          termination of data is *allowed*. When these event are received, the only valid
          input event type is a ``ReadEventType.DATA``.
  
          Generally, ``ReadEventType.NEXT`` is used to get the next parse event, but
          ``ReadEventType.SKIP`` can be used to skip over the current container.
  
          An internal state machine co-routine can delimit a state change without yielding
          to the caller by yielding ``None`` event, this will cause the trampoline to invoke
          the transition delegate, immediately.
      Args:
          start: The reader co-routine to initially delegate to.
          allow_flush(Optional[bool]): True if this reader supports receiving ``NEXT`` after
              yielding ``INCOMPLETE`` to trigger an attempt to flush pending parse events,
              otherwise False.
  
      Yields:
          amazon.ion.core.IonEvent: the result of parsing.
  
          Receives :class:`DataEvent` to parse into :class:`amazon.ion.core.IonEvent`.
      """
      data_event = yield
      if data_event is None or data_event.type is not ReadEventType.NEXT:
          raise TypeError('Reader must be started with NEXT')
      trans = Transition(None, start)
      while True:
          trans = trans.delegate.send(Transition(data_event, trans.delegate))
          data_event = None
          if trans.event is not None:
              # Only yield if there is an event.
              data_event = (yield trans.event)
              if trans.event.event_type.is_stream_signal:
                  if data_event.type is not ReadEventType.DATA:
                      if not allow_flush or not (trans.event.event_type is IonEventType.INCOMPLETE and
                                                 data_event.type is ReadEventType.NEXT):
                          raise TypeError('Reader expected data: %r' % (data_event,))
              else:
                  if data_event.type is ReadEventType.DATA:
                      raise TypeError('Reader did not expect data')
              if data_event.type is ReadEventType.DATA and len(data_event.data) == 0:
                  raise ValueError('Empty data not allowed')
              if trans.event.depth == 0 \
                      and trans.event.event_type is not IonEventType.CONTAINER_START \
                      and data_event.type is ReadEventType.SKIP:
                  raise TypeError('Cannot skip at the top-level')