public IHoconElement Clone(IHoconElement newParent) { var clone = new HoconArray(newParent); clone.AddRange(this); return(clone); }
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); }
internal void ResolveValue(HoconSubstitution child) { var index = IndexOf(child); Remove(child); if (child.Type != HoconType.Empty) { if (Type == HoconType.Empty) { Type = child.Type; } else if (!Type.IsMergeable(child.Type)) { throw HoconParserException.Create(child, child.Path, "Invalid substitution, substituted type be must be mergeable with its sibling type. " + $"Sibling type:{Type}, substitution type:{child.Type}"); } var clonedValue = (HoconValue)child.ResolvedValue.Clone(Parent); switch (Type) { case HoconType.Object: Insert(index, clonedValue.GetObject()); break; case HoconType.Array: var hoconArray = new HoconArray(this); hoconArray.AddRange(clonedValue.GetArray()); Insert(index, hoconArray); break; case HoconType.Boolean: case HoconType.Number: case HoconType.String: var elementList = new List <IHoconElement>(); foreach (var element in clonedValue) { elementList.Add(element); } InsertRange(index, elementList); break; } } switch (Parent) { case HoconField v: v.ResolveValue(this); break; case HoconArray a: a.ResolveValue(child); break; default: throw new Exception($"Invalid parent type while resolving substitution:{Parent.GetType()}"); } }
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); }
private bool Equals(HoconArray other) { if (Count != other.Count) { return(false); } for (var i = 0; i < Count; ++i) { if (!Equals(this[i], other[i])) { return(false); } } return(true); }
/// <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 value token from the tokenizer and appends it /// to the supplied element <paramref name="owner"/>. /// </summary> /// <param name="owner">The element to append the next token.</param> /// <exception cref="System.Exception">End of file reached while trying to read a value</exception> public void ParseValue(HoconValue owner, string currentPath) { if (_reader.EoF) { throw new HoconParserException("End of file reached while trying to read a value"); } _reader.PullWhitespaceAndComments(); var start = _reader.Index; try { while (_reader.IsValue()) { Token t = _reader.PullValue(); switch (t.Type) { case TokenType.EoF: break; case TokenType.LiteralValue: if (owner.IsObject()) { //needed to allow for override objects owner.Clear(); } var lit = new HoconLiteral { Value = t.Value }; owner.AppendValue(lit); break; case TokenType.ObjectStart: ParseObject(owner, true, currentPath); break; case TokenType.ArrayStart: HoconArray arr = ParseArray(currentPath); owner.AppendValue(arr); break; case TokenType.Substitute: HoconSubstitution sub = ParseSubstitution(t.Value); _substitutions.Add(sub); owner.AppendValue(sub); break; } if (_reader.IsSpaceOrTab()) { ParseTrailingWhitespace(owner); } } IgnoreComma(); } catch (HoconTokenizerException tokenizerException) { throw new HoconParserException(string.Format("{0}\r{1}", tokenizerException.Message, GetDiagnosticsStackTrace()), tokenizerException); } finally { //no value was found, tokenizer is still at the same position if (_reader.Index == start) { throw new HoconParserException(string.Format("Hocon syntax error {0}\r{1}", _reader.GetHelpTextAtIndex(start), GetDiagnosticsStackTrace())); } } }
/// <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); }