parseObject function

ValueIndex<ObjectNode>? parseObject(
  1. String input,
  2. List<Token> tokenList,
  3. int index,
  4. Settings settings,
)

Implementation

ValueIndex<ObjectNode>? parseObject(
    String input, List<Token> tokenList, int index, Settings settings) {
  // object: LEFT_BRACE (property (COMMA property)*)? RIGHT_BRACE
  late Token startToken;
  var object = ObjectNode();
  var state = _ObjectState._START_;

  while (index < tokenList.length) {
    final token = tokenList[index];

    switch (state) {
      case _ObjectState._START_:
        {
          if (token.type == TokenType.LEFT_BRACE) {
            startToken = token;
            state = _ObjectState.OPEN_OBJECT;
            index++;
          } else {
            return null;
          }
          break;
        }

      case _ObjectState.OPEN_OBJECT:
        {
          if (token.type == TokenType.RIGHT_BRACE) {
            //  if (settings.loc != null) {
            object = object.copyWith(
                loc: Location.create(
                    startToken.loc!.start.line,
                    startToken.loc!.start.column,
                    startToken.loc!.start.offset,
                    token.loc!.end.line,
                    token.loc!.end.column,
                    token.loc!.end.offset,
                    settings.source));
            //  }
            return ValueIndex(object, index + 1);
          } else {
            final property = parseProperty(input, tokenList, index, settings)!;
            object.children.add(property.value);
            state = _ObjectState.PROPERTY;
            index = property.index;
          }
          break;
        }

      case _ObjectState.PROPERTY:
        {
          if (token.type == TokenType.RIGHT_BRACE) {
            if (settings.loc) {
              object = object.copyWith(
                loc: Location.create(
                  startToken.loc!.start.line,
                  startToken.loc!.start.column,
                  startToken.loc!.start.offset,
                  token.loc!.end.line,
                  token.loc!.end.column,
                  token.loc!.end.offset,
                  settings.source,
                ),
              );
            }
            return ValueIndex(object, index + 1);
          } else if (token.type == TokenType.COMMA) {
            state = _ObjectState.COMMA;
            index++;
          } else {
            final msg = unexpectedToken(
                substring(
                    input, token.loc!.start.offset!, token.loc!.end.offset),
                settings.source,
                token.loc!.start.line,
                token.loc!.start.column);
            throw JSONASTException(msg, input, settings.source,
                token.loc!.start.line, token.loc!.start.column);
          }
          break;
        }

      case _ObjectState.COMMA:
        {
          final property = parseProperty(input, tokenList, index, settings);
          if (property != null) {
            index = property.index;
            object.children.add(property.value);
            state = _ObjectState.PROPERTY;
          } else {
            final msg = unexpectedToken(
                substring(
                    input, token.loc!.start.offset!, token.loc!.end.offset),
                settings.source,
                token.loc!.start.line,
                token.loc!.start.column);
            throw JSONASTException(msg, input, settings.source,
                token.loc!.start.line, token.loc!.start.column);
          }
          break;
        }
    }
  }
  throw errorEof(input, tokenList, settings);
}