code: func (p *Parser) onCDemoPacket(m *dota.CDemoPacket) error {
  	// Create a slice to store pending mesages. Messages are read first as
  	// pending messages then sorted before dispatch.
  	ms := make(pendingMessages, 0, 2)
  
  	// Read all messages from the buffer. Messages are packed serially as
  	// {type, size, data}. We keep reading until until less than a byte remains.
  	r := newReader(m.GetData())
  	for r.remBytes() > 0 {
  		t := int32(r.readUBitVar())
  		size := r.readVarUint32()
  		buf := r.readBytes(size)
  		ms = append(ms, &pendingMessage{p.Tick, t, buf})
  	}
  
  	// Sort messages to ensure dependencies are met. For example, we need to
  	// process string tables before game events that may reference them.
  	sort.Sort(ms)
  
  	// Dispatch messages in order, returning on handler error.
  	for _, m := range ms {
  		if err := p.Callbacks.callByPacketType(m.t, m.buf); err != nil {
  			return err
  		}
  	}
  
  	return nil
  }
docs: // Internal parser for callback OnCDemoPacket, responsible for extracting
  // multiple inner packets from a single CDemoPacket. This is the main structure
  // that contains all other data types in the demo file.