public void Emit(ParsingEvent @event) { // Ignore some events if (@event is StreamStart || @event is StreamEnd || @event is DocumentStart || @event is DocumentEnd) return; parsingEvents.Add(@event); }
public bool MoveNext() { if (++position < parsingEvents.Count) { current = parsingEvents[position]; return true; } return false; }
/// <summary> /// State dispatcher. /// </summary> private void StateMachine(ParsingEvent evt) { switch (state) { case EmitterState.YAML_EMIT_STREAM_START_STATE: EmitStreamStart(evt); break; case EmitterState.YAML_EMIT_FIRST_DOCUMENT_START_STATE: EmitDocumentStart(evt, true); break; case EmitterState.YAML_EMIT_DOCUMENT_START_STATE: EmitDocumentStart(evt, false); break; case EmitterState.YAML_EMIT_DOCUMENT_CONTENT_STATE: EmitDocumentContent(evt); break; case EmitterState.YAML_EMIT_DOCUMENT_END_STATE: EmitDocumentEnd(evt); break; case EmitterState.YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE: EmitFlowSequenceItem(evt, true); break; case EmitterState.YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE: EmitFlowSequenceItem(evt, false); break; case EmitterState.YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE: EmitFlowMappingKey(evt, true); break; case EmitterState.YAML_EMIT_FLOW_MAPPING_KEY_STATE: EmitFlowMappingKey(evt, false); break; case EmitterState.YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE: EmitFlowMappingValue(evt, true); break; case EmitterState.YAML_EMIT_FLOW_MAPPING_VALUE_STATE: EmitFlowMappingValue(evt, false); break; case EmitterState.YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE: EmitBlockSequenceItem(evt, true); break; case EmitterState.YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE: EmitBlockSequenceItem(evt, false); break; case EmitterState.YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE: EmitBlockMappingKey(evt, true); break; case EmitterState.YAML_EMIT_BLOCK_MAPPING_KEY_STATE: EmitBlockMappingKey(evt, false); break; case EmitterState.YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE: EmitBlockMappingValue(evt, true); break; case EmitterState.YAML_EMIT_BLOCK_MAPPING_VALUE_STATE: EmitBlockMappingValue(evt, false); break; case EmitterState.YAML_EMIT_END_STATE: throw new YamlException("Expected nothing after STREAM-END"); default: Debug.Assert(false, "Invalid state."); throw new InvalidOperationException("Invalid state"); } }
/// <summary> /// Check if the evt data is valid. /// </summary> private void AnalyzeEvent(ParsingEvent evt) { anchorData.anchor = null; tagData.handle = null; tagData.suffix = null; AnchorAlias alias = evt as AnchorAlias; if (alias != null) { AnalyzeAnchor(alias.Value, true); return; } NodeEvent nodeEvent = evt as NodeEvent; if (nodeEvent != null) { Scalar scalar = evt as Scalar; if (scalar != null) { AnalyzeScalar(scalar.Value); } AnalyzeAnchor(nodeEvent.Anchor, false); if (!string.IsNullOrEmpty(nodeEvent.Tag) && (isCanonical || nodeEvent.IsCanonical)) { AnalyzeTag(nodeEvent.Tag); } return; } }
/// <summary> /// Emit an evt. /// </summary> public void Emit(ParsingEvent @event) { events.Enqueue(@event); while (!NeedMoreEvents()) { ParsingEvent current = events.Peek(); AnalyzeEvent(current); StateMachine(current); // Only dequeue after calling state_machine because it checks how many events are in the queue. events.Dequeue(); } }
private void AssertEvent(ParsingEvent expected, ParsingEvent actual, int eventNumber) { Assert.AreEqual(expected.GetType(), actual.GetType(), "Parse event {0} is not of the expected type.", eventNumber); foreach (var property in expected.GetType().GetProperties()) { if (property.PropertyType == typeof(Mark) || !property.CanRead) { continue; } var value = property.GetValue(actual, null); var expectedValue = property.GetValue(expected, null); if (expectedValue is IEnumerable && !(expectedValue is string)) { Dump.Write("\t{0} = {{", property.Name); Dump.Write(string.Join(", ", (IEnumerable) value)); Dump.WriteLine("}"); if (expectedValue is ICollection && value is ICollection) { var expectedCount = ((ICollection) expectedValue).Count; var valueCount = ((ICollection) value).Count; Assert.AreEqual(expectedCount, valueCount, "Compared size of collections in property {0} in parse event {1}", property.Name, eventNumber); } var values = ((IEnumerable) value).GetEnumerator(); var expectedValues = ((IEnumerable) expectedValue).GetEnumerator(); while (expectedValues.MoveNext()) { Assert.True(values.MoveNext(), "Property {0} in parse event {1} had too few elements", property.Name, eventNumber); Assert.AreEqual(expectedValues.Current, values.Current, "Compared element in property {0} in parse event {1}", property.Name, eventNumber); } Assert.False(values.MoveNext(), "Property {0} in parse event {1} had too many elements", property.Name, eventNumber); } else { Dump.WriteLine("\t{0} = {1}", property.Name, value); Assert.AreEqual(expectedValue, value, "Compared property {0} in parse event {1}", property.Name, eventNumber); } } }
/// <summary> /// Expect SCALAR. /// </summary> private void EmitScalar(ParsingEvent evt) { SelectScalarStyle(evt); ProcessAnchor(); ProcessTag(); IncreaseIndent(true, false); ProcessScalar(); indent = indents.Pop(); state = states.Pop(); }
/// <summary> /// Expect SEQUENCE-START. /// </summary> private void EmitSequenceStart(ParsingEvent evt) { ProcessAnchor(); ProcessTag(); SequenceStart sequenceStart = (SequenceStart) evt; if (flowLevel != 0 || isCanonical || sequenceStart.Style == DataStyle.Compact || CheckEmptySequence()) { state = EmitterState.YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE; } else { state = EmitterState.YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE; } }
/// <summary> /// Expect the root node. /// </summary> private void EmitDocumentContent(ParsingEvent evt) { states.Push(EmitterState.YAML_EMIT_DOCUMENT_END_STATE); EmitNode(evt, true, false, false); }
/// <summary> /// Expect a flow key node. /// </summary> private void EmitFlowMappingKey(ParsingEvent evt, bool isFirst) { if (isFirst) { WriteIndicator("{", true, true, false); IncreaseIndent(true, false); ++flowLevel; } if (evt is MappingEnd) { --flowLevel; indent = indents.Pop(); if (isCanonical && !isFirst) { WriteIndicator(",", false, false, false); WriteIndent(); } WriteIndicator("}", false, false, false); state = states.Pop(); return; } if (!isFirst) { WriteIndicator(",", false, false, false); } if (isCanonical || column > bestWidth) { WriteIndent(); } if (!isCanonical && CheckSimpleKey()) { states.Push(EmitterState.YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE); EmitNode(evt, false, true, true); } else { WriteIndicator("?", true, false, false); states.Push(EmitterState.YAML_EMIT_FLOW_MAPPING_VALUE_STATE); EmitNode(evt, false, true, false); } }
/// <summary> /// /// Expect a flow item node. /// </summary> private void EmitFlowSequenceItem(ParsingEvent evt, bool isFirst) { if (isFirst) { WriteIndicator("[", true, true, false); IncreaseIndent(true, false); ++flowLevel; } if (evt is SequenceEnd) { --flowLevel; indent = indents.Pop(); if (isCanonical && !isFirst) { WriteIndicator(",", false, false, false); WriteIndent(); } WriteIndicator("]", false, false, false); state = states.Pop(); return; } if (!isFirst) { WriteIndicator(",", false, false, false); } if (isCanonical || column > bestWidth) { WriteIndent(); } states.Push(EmitterState.YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE); EmitNode(evt, false, false, false); }
/// <summary> /// Expect DOCUMENT-END. /// </summary> private void EmitDocumentEnd(ParsingEvent evt) { DocumentEnd documentEnd = evt as DocumentEnd; if (documentEnd != null) { WriteIndent(); if (!documentEnd.IsImplicit) { WriteIndicator("...", true, false, false); WriteIndent(); } state = EmitterState.YAML_EMIT_DOCUMENT_START_STATE; tagDirectives.Clear(); } else { throw new YamlException("Expected DOCUMENT-END."); } }
/// <summary> /// Determine an acceptable scalar style. /// </summary> private void SelectScalarStyle(ParsingEvent evt) { Scalar scalar = (Scalar) evt; ScalarStyle style = scalar.Style; bool noTag = tagData.handle == null && tagData.suffix == null; if (noTag && !scalar.IsPlainImplicit && !scalar.IsQuotedImplicit) { throw new YamlException("Neither tag nor isImplicit flags are specified."); } if (style == ScalarStyle.Any) { style = scalarData.isMultiline ? ScalarStyle.Folded : ScalarStyle.Plain; } if (isCanonical) { style = ScalarStyle.DoubleQuoted; } if (isSimpleKeyContext && scalarData.isMultiline) { style = ScalarStyle.DoubleQuoted; } if (style == ScalarStyle.Plain) { if ((flowLevel != 0 && !scalarData.isFlowPlainAllowed) || (flowLevel == 0 && !scalarData.isBlockPlainAllowed)) { style = ScalarStyle.SingleQuoted; } if (string.IsNullOrEmpty(scalarData.value) && (flowLevel != 0 || isSimpleKeyContext)) { style = ScalarStyle.SingleQuoted; } if (noTag && !scalar.IsPlainImplicit) { style = ScalarStyle.SingleQuoted; } } if (style == ScalarStyle.SingleQuoted) { if (!scalarData.isSingleQuotedAllowed) { style = ScalarStyle.DoubleQuoted; } } if (style == ScalarStyle.Literal || style == ScalarStyle.Folded) { if (!scalarData.isBlockAllowed || flowLevel != 0 || isSimpleKeyContext) { style = ScalarStyle.DoubleQuoted; } } // TODO: What is this code supposed to mean? //if (noTag && !scalar.IsQuotedImplicit && style != ScalarStyle.Plain) //{ // tagData.handle = "!"; //} scalarData.style = style; }
public virtual void Emit(ParsingEvent parsingEvent) { nextEmitter.Emit(parsingEvent); }
/// <summary> /// Expect STREAM-START. /// </summary> private void EmitStreamStart(ParsingEvent evt) { if (!(evt is StreamStart)) { throw new ArgumentException("Expected STREAM-START.", "evt"); } indent = -1; line = 0; column = 0; isWhitespace = true; isIndentation = true; state = EmitterState.YAML_EMIT_FIRST_DOCUMENT_START_STATE; }
/// <summary> /// Expect a flow value node. /// </summary> private void EmitFlowMappingValue(ParsingEvent evt, bool isSimple) { if (isSimple) { WriteIndicator(":", false, false, false); } else { if (isCanonical || column > bestWidth) { WriteIndent(); } WriteIndicator(":", true, false, false); } states.Push(EmitterState.YAML_EMIT_FLOW_MAPPING_KEY_STATE); EmitNode(evt, false, true, false); }
/// <summary> /// Expect DOCUMENT-START or STREAM-END. /// </summary> private void EmitDocumentStart(ParsingEvent evt, bool isFirst) { DocumentStart documentStart = evt as DocumentStart; if (documentStart != null) { bool isImplicit = documentStart.IsImplicit && isFirst && !isCanonical; if (documentStart.Version != null && isOpenEnded) { WriteIndicator("...", true, false, false); WriteIndent(); } if (documentStart.Version != null) { AnalyzeVersionDirective(documentStart.Version); isImplicit = false; WriteIndicator("%YAML", true, false, false); WriteIndicator(string.Format(CultureInfo.InvariantCulture, "{0}.{1}", Constants.MajorVersion, Constants.MinorVersion), true, false, false); WriteIndent(); } if (documentStart.Tags != null) { foreach (var tagDirective in documentStart.Tags) { AppendTagDirective(tagDirective, false); } } foreach (var tagDirective in Constants.DefaultTagDirectives) { AppendTagDirective(tagDirective, true); } if (documentStart.Tags != null && documentStart.Tags.Count != 0) { isImplicit = false; foreach (var tagDirective in documentStart.Tags) { WriteIndicator("%TAG", true, false, false); WriteTagHandle(tagDirective.Handle); WriteTagContent(tagDirective.Prefix, true); WriteIndent(); } } if (CheckEmptyDocument()) { isImplicit = false; } if (!isImplicit) { WriteIndent(); WriteIndicator("---", true, false, false); if (isCanonical) { WriteIndent(); } } state = EmitterState.YAML_EMIT_DOCUMENT_CONTENT_STATE; } else if (evt is StreamEnd) { if (isOpenEnded) { WriteIndicator("...", true, false, false); WriteIndent(); } state = EmitterState.YAML_EMIT_END_STATE; } else { throw new YamlException("Expected DOCUMENT-START or STREAM-END"); } }
/// <summary> /// Expect a block item node. /// </summary> private void EmitBlockSequenceItem(ParsingEvent evt, bool isFirst) { if (isFirst) { IncreaseIndent(false, (isMappingContext && !isIndentation)); } if (evt is SequenceEnd) { indent = indents.Pop(); state = states.Pop(); return; } WriteIndent(); WriteIndicator("-", true, false, true); states.Push(EmitterState.YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE); EmitNode(evt, false, false, false); }
/// <summary> /// Expect a node. /// </summary> private void EmitNode(ParsingEvent evt, bool isRoot, bool isMapping, bool isSimpleKey) { isRootContext = isRoot; isMappingContext = isMapping; isSimpleKeyContext = isSimpleKey; var eventType = evt.Type; switch (eventType) { case EventType.YAML_ALIAS_EVENT: EmitAlias(); break; case EventType.YAML_SCALAR_EVENT: EmitScalar(evt); break; case EventType.YAML_SEQUENCE_START_EVENT: EmitSequenceStart(evt); break; case EventType.YAML_MAPPING_START_EVENT: EmitMappingStart(evt); break; default: throw new YamlException(string.Format("Expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, got {0}", eventType)); } }
/// <summary> /// Expect a block key node. /// </summary> private void EmitBlockMappingKey(ParsingEvent evt, bool isFirst) { if (isFirst) { IncreaseIndent(false, false); } if (evt is MappingEnd) { indent = indents.Pop(); state = states.Pop(); return; } WriteIndent(); if (CheckSimpleKey()) { states.Push(EmitterState.YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE); EmitNode(evt, false, true, true); } else { WriteIndicator("?", true, false, true); states.Push(EmitterState.YAML_EMIT_BLOCK_MAPPING_VALUE_STATE); EmitNode(evt, false, true, false); } }
/// <summary> /// Expect MAPPING-START. /// </summary> private void EmitMappingStart(ParsingEvent evt) { ProcessAnchor(); ProcessTag(); MappingStart mappingStart = (MappingStart) evt; if (flowLevel != 0 || isCanonical || mappingStart.Style == DataStyle.Compact || CheckEmptyMapping()) { state = EmitterState.YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE; } else { state = EmitterState.YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE; } }
/// <summary> /// Expect a block value node. /// </summary> private void EmitBlockMappingValue(ParsingEvent evt, bool isSimple) { if (isSimple) { WriteIndicator(":", false, false, false); } else { WriteIndent(); WriteIndicator(":", true, false, true); } states.Push(EmitterState.YAML_EMIT_BLOCK_MAPPING_KEY_STATE); EmitNode(evt, false, true, false); }
public void Emit(ParsingEvent parsingEvent) { emitter.Emit(parsingEvent); }
public override void Emit(ParsingEvent parsingEvent) { events.Add(parsingEvent); }