public bool Equals(IHoconElement other) { if (other is null) { return(false); } if (ReferenceEquals(this, other)) { return(true); } if (other.Type != HoconType.Object) { return(false); } return(this.AsEnumerable().SequenceEqual(other.GetObject().AsEnumerable())); }
// The owner in this context can be either an object or an array. private HoconObject ParseObject(IHoconElement owner) { var hoconObject = new HoconObject(owner); if (_tokens.Current.Type != TokenType.StartOfObject && _tokens.Current.Type != TokenType.LiteralValue && _tokens.Current.Type != TokenType.Include) { throw HoconParserException.Create(_tokens.Current, Path, $"Failed to parse Hocon object. Expected `{TokenType.StartOfObject}` or `{TokenType.LiteralValue}, " + $"found `{_tokens.Current.Type}` instead."); } var headless = true; if (_tokens.Current.Type == TokenType.StartOfObject) { headless = false; 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 object. Expected `{TokenType.Comma}` or `{TokenType.EndOfLine}`, " + $"found `{_tokens.Current.Type}` instead."); } lastValue = ParseInclude(hoconObject); break; case TokenType.LiteralValue: if (_tokens.Current.IsNonSignificant()) { ConsumeWhitespace(); } if (_tokens.Current.Type != TokenType.LiteralValue) { break; } if (lastValue != null) { throw HoconParserException.Create(_tokens.Current, Path, $"Failed to parse Hocon object. Expected `{TokenType.Comma}` or `{TokenType.EndOfLine}`, " + $"found `{_tokens.Current.Type}` instead."); } lastValue = ParseField(hoconObject); break; // TODO: can an object be declared floating without being assigned to a field? //case TokenType.StartOfObject: case TokenType.Comment: case TokenType.EndOfLine: switch (lastValue) { case null: ConsumeWhitelines(); break; case HoconField _: break; default: ((HoconValue)hoconObject.Parent).Add(lastValue.GetObject()); break; } lastValue = null; ConsumeWhitelines(); break; case TokenType.Comma: switch (lastValue) { case null: throw HoconParserException.Create(_tokens.Current, Path, $"Failed to parse Hocon object. Expected `{TokenType.Assign}` or `{TokenType.StartOfObject}`, " + $"found `{_tokens.Current.Type}` instead."); case HoconField _: break; default: ((HoconValue)hoconObject.Parent).Add(lastValue.GetObject()); break; } lastValue = null; ConsumeWhitelines(); break; case TokenType.EndOfObject: case TokenType.EndOfFile: if (headless && _tokens.Current.Type != TokenType.EndOfFile) { throw HoconParserException.Create(_tokens.Current, Path, $"Failed to parse Hocon object. Expected {TokenType.EndOfFile} but found {_tokens.Current.Type} instead."); } if (!headless && _tokens.Current.Type != TokenType.EndOfObject) { throw HoconParserException.Create(_tokens.Current, Path, $"Failed to parse Hocon object. Expected {TokenType.EndOfObject} but found {_tokens.Current.Type} instead."); } switch (lastValue) { case null: break; case HoconField _: break; default: ((HoconValue)hoconObject.Parent).Add(lastValue.GetObject()); break; } lastValue = null; parsing = false; break; default: throw HoconParserException.Create(_tokens.Current, Path, $"Failed to parse Hocon object. Unexpected token `{_tokens.Current.Type}`."); } } if (_tokens.Current.Type == TokenType.EndOfObject) { _tokens.Next(); } return(hoconObject); }