private HoconArray ParsePlusEqualAssignArray(IHoconElement owner) { // sanity check if (_tokens.Current.Type != TokenType.PlusEqualAssign) { throw HoconParserException.Create(_tokens.Current, Path, "Failed to parse Hocon field with += operator. " + $"Expected {TokenType.PlusEqualAssign}, found {{_tokens.Current.Type}} instead."); } var currentArray = new HoconArray(owner); // consume += operator token ConsumeWhitelines(); switch (_tokens.Current.Type) { case TokenType.Include: currentArray.Add(ParseInclude(currentArray)); break; case TokenType.StartOfArray: // Array inside of arrays are parsed as values because it can be value concatenated with another array. currentArray.Add(ParseValue(currentArray)); break; case TokenType.StartOfObject: currentArray.Add(ParseObject(currentArray)); break; case TokenType.LiteralValue: if (_tokens.Current.IsNonSignificant()) { ConsumeWhitelines(); } if (_tokens.Current.Type != TokenType.LiteralValue) { break; } currentArray.Add(ParseValue(currentArray)); break; case TokenType.SubstituteOptional: case TokenType.SubstituteRequired: var pointerPath = HoconPath.Parse(_tokens.Current.Value); HoconSubstitution sub = new HoconSubstitution(currentArray, pointerPath, _tokens.Current, _tokens.Current.Type == TokenType.SubstituteRequired); _substitutions.Add(sub); currentArray.Add(sub); _tokens.Next(); break; default: throw HoconParserException.Create(_tokens.Current, Path, $"Failed to parse Hocon array. Expected {TokenType.EndOfArray} but found {_tokens.Current.Type} instead."); } return(currentArray); }
private static void Flatten(IHoconElement node) { if (!(node is HoconValue v)) { return; } switch (v.Type) { case HoconType.Object: var o = v.GetObject(); v.Clear(); v.Add(o); foreach (var item in o.Values) { Flatten(item); } break; case HoconType.Array: var a = v.GetArray(); v.Clear(); var newArray = new HoconArray(v); foreach (var item in a) { Flatten(item); newArray.Add(item); } v.Add(newArray); break; case HoconType.Literal: if (v.Count == 1) { return; } var value = v.GetString(); v.Clear(); if (value == null) { v.Add(new HoconNull(v)); } else if (value.NeedTripleQuotes()) { v.Add(new HoconTripleQuotedString(v, value)); } else if (value.NeedQuotes()) { v.Add(new HoconQuotedString(v, value)); } else { v.Add(new HoconUnquotedString(v, value)); } break; } }
public IHoconElement Clone(IHoconElement newParent) { var newArray = new HoconArray(newParent); foreach (var value in this) { newArray.Add(value.Clone(newArray) as HoconValue); } return(newArray); }
/// <summary> /// Retrieves the next array token from the tokenizer. /// </summary> /// <returns>An array of elements retrieved from the token.</returns> public HoconArray ParseArray(string currentPath) { try { PushDiagnostics("["); var arr = new HoconArray(); while (!_reader.EoF && !_reader.IsArrayEnd()) { var v = new HoconValue(); ParseValue(v, currentPath); arr.Add(v); _reader.PullWhitespaceAndComments(); } _reader.PullArrayEnd(); return(arr); } finally { PopDiagnostics(); } }
/// <summary> /// Retrieves the next array token from the tokenizer. /// </summary> /// <returns>An array of elements retrieved from the token.</returns> private HoconArray ParseArray(IHoconElement owner) { // sanity check if (_tokens.Current.Type != TokenType.StartOfArray) { throw HoconParserException.Create(_tokens.Current, Path, "Failed to parse Hocon array. " + $"Expected {TokenType.StartOfArray}, found {_tokens.Current.Type} instead."); } var currentArray = new HoconArray(owner); // consume start of array token _tokens.ToNextSignificant(); var valueWasParsed = false; var parsing = true; while (parsing) { switch (_tokens.Current.Type) { case TokenType.Include: if (valueWasParsed) { throw HoconParserException.Create(_tokens.Current, Path, $"Failed to parse Hocon array. Expected `{TokenType.Comma}` or `{TokenType.EndOfLine}, " + $"found `{_tokens.Current.Type}` instead."); } currentArray.Add(ParseValue(currentArray)); valueWasParsed = true; break; case TokenType.LiteralValue: if (_tokens.Current.IsNonSignificant()) { _tokens.ToNextSignificant(); } if (_tokens.Current.Type != TokenType.LiteralValue) { break; } if (valueWasParsed) { throw HoconParserException.Create(_tokens.Current, Path, $"Failed to parse Hocon array. Expected `{TokenType.Comma}` or `{TokenType.EndOfLine}, " + $"found `{_tokens.Current.Type}` instead."); } currentArray.Add(ParseValue(currentArray)); valueWasParsed = true; break; case TokenType.StartOfObject: if (valueWasParsed) { throw HoconParserException.Create(_tokens.Current, Path, $"Failed to parse Hocon array. Expected `{TokenType.Comma}` or `{TokenType.EndOfLine}, " + $"found `{_tokens.Current.Type}` instead."); } currentArray.Add(ParseValue(currentArray)); valueWasParsed = true; break; case TokenType.StartOfArray: if (valueWasParsed) { throw HoconParserException.Create(_tokens.Current, Path, $"Failed to parse Hocon array. Expected `{TokenType.Comma}` or `{TokenType.EndOfLine}, " + $"found `{_tokens.Current.Type}` instead."); } // Array inside of arrays are parsed as values because it can be value concatenated with another array. currentArray.Add(ParseValue(currentArray)); valueWasParsed = true; break; case TokenType.SubstituteOptional: case TokenType.SubstituteRequired: if (valueWasParsed) { throw HoconParserException.Create(_tokens.Current, Path, $"Failed to parse Hocon array. Expected `{TokenType.Comma}` or `{TokenType.EndOfLine}, " + $"found `{_tokens.Current.Type}` instead."); } currentArray.Add(ParseValue(currentArray)); valueWasParsed = true; break; case TokenType.EndOfArray: valueWasParsed = false; // If there is a next array on the same like - let's move to it's first element if (_tokens.ForwardMatch(TokenType.StartOfArray)) { _tokens.ToNextSignificant(); _tokens.Next(); } else { // Otherwise, array value is fully loaded and nothing to do here parsing = false; } break; case TokenType.Comment: case TokenType.EndOfLine: valueWasParsed = false; _tokens.ToNextSignificantLine(); break; case TokenType.Comma: if (!valueWasParsed) { throw HoconParserException.Create(_tokens.Current, Path, $"Failed to parse Hocon array. Expected a valid value, found `{_tokens.Current.Type}` instead."); } valueWasParsed = false; _tokens.ToNextSignificant(); break; default: throw HoconParserException.Create(_tokens.Current, Path, $"Failed to parse Hocon array. Expected {TokenType.EndOfArray} but found {_tokens.Current.Type} instead."); } } // Consume end of array token _tokens.Next(); return(currentArray); }
private HoconArray ParsePlusEqualAssignArray(IHoconElement owner) { // sanity check if (_tokens.Current.Type != TokenType.PlusEqualAssign) { throw HoconParserException.Create(_tokens.Current, Path, "Failed to parse Hocon field with += operator. " + $"Expected {TokenType.PlusEqualAssign}, found {_tokens.Current.Type} instead."); } var currentArray = new HoconArray(owner); // consume += operator token _tokens.ToNextSignificant(); switch (_tokens.Current.Type) { case TokenType.Include: var includeToken = _tokens.Current; var includeValue = ParseInclude(); if (includeValue.Type == HoconType.Empty) { break; } if (currentArray.Type != HoconType.Empty && currentArray.Type != includeValue.Type) { throw HoconParserException.Create(includeToken, Path, "Invalid Hocon include. Hocon config substitution type must be the same as the field it's merged into. " + $"Expected type: `{currentArray.Type}`, type returned by include callback: `{includeValue.Type}`"); } currentArray.Add((HoconValue)includeValue.Clone(currentArray)); break; case TokenType.StartOfArray: // Array inside of arrays are parsed as values because it can be value concatenated with another array. currentArray.Add(ParseValue(currentArray)); break; case TokenType.StartOfObject: currentArray.Add(ParseValue(currentArray)); break; case TokenType.LiteralValue: if (_tokens.Current.IsNonSignificant()) { _tokens.ToNextSignificant(); } if (_tokens.Current.Type != TokenType.LiteralValue) { break; } currentArray.Add(ParseValue(currentArray)); break; case TokenType.SubstituteOptional: case TokenType.SubstituteRequired: currentArray.Add(ParseValue(currentArray)); break; default: throw HoconParserException.Create(_tokens.Current, Path, $"Failed to parse Hocon array. Expected {TokenType.EndOfArray} but found {_tokens.Current.Type} instead."); } return(currentArray); }
/// <summary> /// Retrieves the next array token from the tokenizer. /// </summary> /// <returns>An array of elements retrieved from the token.</returns> private HoconArray ParseArray(IHoconElement owner) { var currentArray = new HoconArray(owner); // consume start of array token ConsumeWhitelines(); IHoconElement lastValue = null; var parsing = true; while (parsing) { switch (_tokens.Current.Type) { case TokenType.Include: if (lastValue != null) { throw HoconParserException.Create(_tokens.Current, Path, $"Failed to parse Hocon array. Expected `{TokenType.Comma}` or `{TokenType.EndOfLine}, " + $"found `{_tokens.Current.Type}` instead."); } lastValue = ParseInclude(currentArray); break; case TokenType.StartOfArray: if (lastValue != null) { throw HoconParserException.Create(_tokens.Current, Path, $"Failed to parse Hocon array. Expected `{TokenType.Comma}` or `{TokenType.EndOfLine}, " + $"found `{_tokens.Current.Type}` instead."); } // Array inside of arrays are parsed as values because it can be value concatenated with another array. lastValue = ParseValue(currentArray); break; case TokenType.StartOfObject: if (lastValue != null) { throw HoconParserException.Create(_tokens.Current, Path, $"Failed to parse Hocon array. Expected `{TokenType.Comma}` or `{TokenType.EndOfLine}, " + $"found `{_tokens.Current.Type}` instead."); } lastValue = ParseObject(currentArray); break; case TokenType.LiteralValue: if (_tokens.Current.IsNonSignificant()) { ConsumeWhitelines(); } if (_tokens.Current.Type != TokenType.LiteralValue) { break; } if (lastValue != null) { throw HoconParserException.Create(_tokens.Current, Path, $"Failed to parse Hocon array. Expected `{TokenType.Comma}` or `{TokenType.EndOfLine}, " + $"found `{_tokens.Current.Type}` instead."); } lastValue = ParseValue(currentArray); break; case TokenType.SubstituteOptional: case TokenType.SubstituteRequired: if (lastValue != null) { throw HoconParserException.Create(_tokens.Current, Path, $"Failed to parse Hocon array. Expected `{TokenType.Comma}` or `{TokenType.EndOfLine}, " + $"found `{_tokens.Current.Type}` instead."); } var pointerPath = HoconPath.Parse(_tokens.Current.Value); HoconSubstitution sub = new HoconSubstitution(currentArray, pointerPath, _tokens.Current, _tokens.Current.Type == TokenType.SubstituteRequired); _substitutions.Add(sub); lastValue = sub; _tokens.Next(); break; case TokenType.Comment: case TokenType.EndOfLine: if (lastValue == null) { ConsumeWhitelines(); break; } switch (lastValue.Type) { case HoconType.Array: currentArray.Add(lastValue); break; default: currentArray.Add(lastValue); break; } lastValue = null; ConsumeWhitelines(); break; case TokenType.Comma: if (lastValue == null) { throw HoconParserException.Create(_tokens.Current, Path, $"Failed to parse Hocon array. Expected a valid value, found `{_tokens.Current.Type}` instead."); } switch (lastValue.Type) { case HoconType.Array: currentArray.Add(lastValue); break; default: currentArray.Add(lastValue); break; } lastValue = null; ConsumeWhitelines(); break; case TokenType.EndOfArray: if (lastValue != null) { switch (lastValue.Type) { case HoconType.Array: currentArray.Add(lastValue); break; default: currentArray.Add(lastValue); break; } lastValue = null; } parsing = false; break; default: throw HoconParserException.Create(_tokens.Current, Path, $"Failed to parse Hocon array. Expected {TokenType.EndOfArray} but found {_tokens.Current.Type} instead."); } } // Consume end of array token _tokens.Next(); return(currentArray); }