/// <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="Exception">End of file reached while trying to read a value</exception> private JsonPlusValue ParseValue(IJsonPlusNode owner) { JsonPlusValue value = new JsonPlusValue(owner); bool parsing = true; while (parsing) { switch (_tokens.Current.Type) { case TokenType.Include: case TokenType.OptionalInclude: value.Add(ParseInclude(value)); break; case TokenType.LiteralValue: // Consume leading whitespaces. if (_tokens.Current.IsNonSignificant()) { ConsumeWhitespace(); } if (_tokens.Current.Type != TokenType.LiteralValue) { break; } while (_tokens.Current.Type == TokenType.LiteralValue) { value.Add(JsonPlusLiteralValue.Create(value, _tokens.Current)); _tokens.Next(); } break; case TokenType.StartOfObject: value.Add(ParseObject(value)); break; case TokenType.StartOfArray: value.Add(ParseArray(value)); break; case TokenType.OptionalSubstitution: case TokenType.Substitution: JsonPlusPath pointerPath = JsonPlusPath.Parse(_tokens.Current.Value); JsonPlusSubstitution sub = new JsonPlusSubstitution(value, pointerPath, _tokens.Current, _tokens.Current.Type == TokenType.Substitution); _substitutions.Add(sub); value.Add(sub); _tokens.Next(); break; case TokenType.EndOfObject: case TokenType.EndOfArray: parsing = false; break; // comments automatically stop value parsing. case TokenType.Comment: ConsumeWhitelines(); parsing = false; break; case TokenType.EndOfLine: parsing = false; break; case TokenType.EndOfFile: case TokenType.ArraySeparator: parsing = false; break; case TokenType.SelfAssignment: JsonPlusSubstitution subAssign = new JsonPlusSubstitution(value, new JsonPlusPath(Path), _tokens.Current, false); _substitutions.Add(subAssign); value.Add(subAssign); value.Add(ParseSelfAssignArray(value)); parsing = false; break; case TokenType.Assignment: ConsumeWhitelines(); break; default: throw JsonPlusParserException.Create(_tokens.Current, Path, string.Format(RS.ErrAtUnexpectedToken, _tokens.Current.Type)); } } // trim trailing whitespace if result is a literal if (value.Type == JsonPlusType.Literal) { if (value[value.Count - 1] is WhitespaceValue) { value.RemoveAt(value.Count - 1); } } return(value); }