Which stages of sidechain exist in which situations?

I started writing a class that sits in my AudioProcessor and it’s supposed to organise what different buses are doing. Whenever processBlock begins this method is called:

void updateBuffers(AudioProcessor& p, AudioBufferD& buffer, bool standalone) noexcept
		{
			busMain = p.getBus(true, 0);
			bufferMain = busMain->getBusBuffer(buffer);
			numChannels = bufferMain.getNumChannels();
			samplesMain = bufferMain.getArrayOfWritePointers();
			samplesMainRead = bufferMain.getArrayOfReadPointers();
			if (!standalone)
			{
				busSC = p.getBus(true, 1);
				if (busSC != nullptr)
				{
					if (busSC->isEnabled())
					{
						bufferSC = busSC->getBusBuffer(buffer);
						samplesSC = bufferSC.getArrayOfWritePointers();
						samplesSCRead = bufferSC.getArrayOfReadPointers();
						enabled = true;
						DBG("stage3");
						return;
					}
					DBG("stage2");
					return;
				}
				DBG("stage1");
				return;
			}
			DBG("stage0");
			bufferSC = bufferMain;
			samplesSC = samplesMain;
			samplesSCRead = samplesMainRead;
			enabled = false;
		}

As you can see the input parameters are the current audio processor, for getting the buses, the current buffer and a bool for if this is a standalone build.

All variables that have “bus” at the beginning are juce::AudioProcessor::Bus pointers.
All variables that have “buffer” at the beginning are juce::AudioBuffer objects.
All variables with “samples” at the beginning are float* const* or const float* const*.

So as you can see the method is supposed to prepare all these variables so i can work with them easily in the upcoming stuff in the processBlock call. And I have put some DBG there atm, to figure out where I even end up in different situations of sidechaining.

The easiest case is stage0, standalone, that is always triggered when the app runs with the standalone wrapper. There I just let the sidechain buffer be the main buffer. The idea is: The upcoming code might think it uses a sidechain buffer, but it doesn’t actually.

The 2nd-easiest case to grasp is stage3, the one that is triggered, when the sidechain input is activated in the plugin. I tested this to be true in cubase, whenever that sidechain-button on top of the plugin UI is enabled. Interestingly it always gives me 2 channels, even if the sidechain input is from a mono track.

I was also able to trigger stage2, by loading the plugin and not enabling the sidechain-button in cubase. Then I had 2 channels, just as expected.

Now I’m wondering 2 things:

  1. Is this behaviour consistent across different DAWs so far? It looks pretty nice and predictable.
  2. What triggers stage 1 actually? It would mean that there is no sidechain bus. The sidechain bus is nullptr. But why would it be nullptr? Even deactivated sidechain doesn’t just remove the bus, which is why it falls into stage 2. So when is stage 1 a thing? What is this pointer there for?