internal override void Execute(Processor processor, ActionFrame frame)
{
Debug.Assert(processor != null && frame != null && frame.State != ValueCalculated);
object value = null;
switch (frame.State)
{
case Initialized:
if (IsGlobal)
{
if (frame.GetVariable(_varKey) != null)
{ // This var was calculated already
frame.Finished();
break;
}
// Mark that the variable is being computed to check for circular references
frame.SetVariable(_varKey, BeingComputedMark);
}
// If this is a parameter, check whether the caller has passed the value
if (this.varType == VariableType.GlobalParameter)
{
value = processor.GetGlobalParameter(this.name);
}
else if (this.varType == VariableType.LocalParameter)
{
value = processor.GetParameter(this.name);
}
if (value != null)
{
goto case ValueCalculated;
}
// If value was not passed, check the 'select' attribute
if (this.selectKey != Compiler.InvalidQueryKey)
{
value = processor.RunQuery(frame, this.selectKey);
goto case ValueCalculated;
}
// If there is no 'select' attribute and the content is empty, use the empty string
if (this.containedActions == null)
{
value = string.Empty;
goto case ValueCalculated;
}
// RTF case
NavigatorOutput output = new NavigatorOutput(this.baseUri);
processor.PushOutput(output);
processor.PushActionFrame(frame);
frame.State = ProcessingChildren;
break;
case ProcessingChildren:
RecordOutput recOutput = processor.PopOutput();
Debug.Assert(recOutput is NavigatorOutput);
value = ((NavigatorOutput)recOutput).Navigator;
goto case ValueCalculated;
case ValueCalculated:
Debug.Assert(value != null);
frame.SetVariable(_varKey, value);
frame.Finished();
break;
default:
Debug.Fail("Invalid execution state inside VariableAction.Execute");
break;
}
}