//===--- ParsedRawSyntaxNode.h - Parsed Raw Syntax Node ---------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_PARSE_PARSEDRAWSYNTAXNODE_H
#define SWIFT_PARSE_PARSEDRAWSYNTAXNODE_H

#include "swift/Basic/SourceLoc.h"
#include "swift/Parse/ParsedTrivia.h"
#include "swift/Parse/Token.h"
#include "swift/Syntax/SyntaxKind.h"
#include <vector>

namespace swift {

typedef void *OpaqueSyntaxNode;
class SyntaxParsingContext;

/// Represents a raw syntax node formed by the parser.
///
/// It can be either 'recorded', in which case it encapsulates an
/// \c OpaqueSyntaxNode that was returned from a \c SyntaxParseActions
/// invocation, or 'deferred' which captures the data for a
/// \c SyntaxParseActions invocation to occur later.
///
/// An \c OpaqueSyntaxNode can represent both the result of 'recording' a token
/// as well as 'recording' a syntax layout, so there's only one
/// \c RecordedSyntaxNode structure that can represent both.
///
/// The 'deferred' form is used for when the parser is backtracking and when
/// there are instances that it's not clear what will be the final syntax node
/// in the current parsing context.
class ParsedRawSyntaxNode {
  enum class DataKind: uint8_t {
    Null,
    Recorded,
    DeferredLayout,
    DeferredToken,
  };

  struct RecordedSyntaxNode {
    OpaqueSyntaxNode OpaqueNode;
    CharSourceRange Range;
  };
  struct DeferredLayoutNode {
    ArrayRef<ParsedRawSyntaxNode> Children;
  };
  struct DeferredTokenNode {
    const ParsedTriviaPiece *TriviaPieces;
    SourceLoc TokLoc;
    unsigned TokLength;
    uint16_t NumLeadingTrivia;
    uint16_t NumTrailingTrivia;
  };

  union {
    RecordedSyntaxNode RecordedData;
    DeferredLayoutNode DeferredLayout;
    DeferredTokenNode DeferredToken;
  };
  uint16_t SynKind;
  uint16_t TokKind;
  DataKind DK;
  /// Primary used for capturing a deferred missing token.
  bool IsMissing = false;

  ParsedRawSyntaxNode(syntax::SyntaxKind k,
                      ArrayRef<ParsedRawSyntaxNode> deferredNodes)
    : DeferredLayout{deferredNodes},
      SynKind(uint16_t(k)), TokKind(uint16_t(tok::unknown)),
      DK(DataKind::DeferredLayout) {
    assert(getKind() == k && "Syntax kind with too large value!");
  }

  ParsedRawSyntaxNode(tok tokKind, SourceLoc tokLoc, unsigned tokLength,
                      const ParsedTriviaPiece *triviaPieces,
                      unsigned numLeadingTrivia,
                      unsigned numTrailingTrivia)
    : DeferredToken{triviaPieces,
                    tokLoc, tokLength,
                    uint16_t(numLeadingTrivia),
                    uint16_t(numTrailingTrivia)},
      SynKind(uint16_t(syntax::SyntaxKind::Token)),
      TokKind(uint16_t(tokKind)),
      DK(DataKind::DeferredToken) {
    assert(getTokenKind() == tokKind && "Token kind is too large value!");
    assert(DeferredToken.NumLeadingTrivia == numLeadingTrivia &&
           "numLeadingTrivia is too large value!");
    assert(DeferredToken.NumTrailingTrivia == numTrailingTrivia &&
           "numLeadingTrivia is too large value!");
  }

public:
  ParsedRawSyntaxNode()
    : RecordedData{},
      SynKind(uint16_t(syntax::SyntaxKind::Unknown)),
      TokKind(uint16_t(tok::unknown)),
      DK(DataKind::Null) {
  }

  ParsedRawSyntaxNode(syntax::SyntaxKind k, tok tokKind,
                      CharSourceRange r, OpaqueSyntaxNode n)
    : RecordedData{n, r},
      SynKind(uint16_t(k)), TokKind(uint16_t(tokKind)),
      DK(DataKind::Recorded) {
    assert(getKind() == k && "Syntax kind with too large value!");
    assert(getTokenKind() == tokKind && "Token kind with too large value!");
  }

  syntax::SyntaxKind getKind() const { return syntax::SyntaxKind(SynKind); }
  tok getTokenKind() const { return tok(TokKind); }

  bool isToken() const {
    return getKind() == syntax::SyntaxKind::Token;
  }
  bool isToken(tok tokKind) const {
    return getTokenKind() == tokKind;
  }

  bool isNull() const {
    return DK == DataKind::Null;
  }

  bool isRecorded() const { return DK == DataKind::Recorded; }
  bool isDeferredLayout() const { return DK == DataKind::DeferredLayout; }
  bool isDeferredToken() const { return DK == DataKind::DeferredToken; }

  /// Primary used for a deferred missing token.
  bool isMissing() const { return IsMissing; }

  // Recorded Data ===========================================================//

  CharSourceRange getRange() const {
    assert(isRecorded());
    return RecordedData.Range;
  }
  OpaqueSyntaxNode getOpaqueNode() const {
    assert(isRecorded());
    return RecordedData.OpaqueNode;
  }

  // Deferred Layout Data ====================================================//

  ArrayRef<ParsedRawSyntaxNode> getDeferredChildren() const {
    assert(DK == DataKind::DeferredLayout);
    return DeferredLayout.Children;
  }

  // Deferred Token Data =====================================================//

  CharSourceRange getDeferredTokenRangeWithoutBackticks() const {
    assert(DK == DataKind::DeferredToken);
    return CharSourceRange{DeferredToken.TokLoc, DeferredToken.TokLength};
  }
  ArrayRef<ParsedTriviaPiece> getDeferredLeadingTriviaPieces() const {
    assert(DK == DataKind::DeferredToken);
    return ArrayRef<ParsedTriviaPiece>(DeferredToken.TriviaPieces,
                                       DeferredToken.NumLeadingTrivia);
  }
  ArrayRef<ParsedTriviaPiece> getDeferredTrailingTriviaPieces() const {
    assert(DK == DataKind::DeferredToken);
    return ArrayRef<ParsedTriviaPiece>(
      DeferredToken.TriviaPieces + DeferredToken.NumLeadingTrivia,
      DeferredToken.NumTrailingTrivia);
  }

  //==========================================================================//

  /// Form a deferred syntax layout node.
  static ParsedRawSyntaxNode makeDeferred(syntax::SyntaxKind k,
                        ArrayRef<ParsedRawSyntaxNode> deferredNodes,
                                          SyntaxParsingContext &ctx);

  /// Form a deferred token node.
  static ParsedRawSyntaxNode makeDeferred(Token tok,
                                          const ParsedTrivia &leadingTrivia,
                                          const ParsedTrivia &trailingTrivia,
                                          SyntaxParsingContext &ctx);

  /// Form a deferred missing token node.
  static ParsedRawSyntaxNode makeDeferredMissing(tok tokKind, SourceLoc loc) {
    auto raw = ParsedRawSyntaxNode(tokKind, loc, 0, nullptr, 0, 0);
    raw.IsMissing = true;
    return raw;
  }

  /// Dump this piece of syntax recursively for debugging or testing.
  LLVM_ATTRIBUTE_DEPRECATED(
    void dump() const LLVM_ATTRIBUTE_USED,
    "only for use within the debugger");

  /// Dump this piece of syntax recursively.
  void dump(raw_ostream &OS, unsigned Indent = 0) const;

  static ParsedRawSyntaxNode null() {
    return ParsedRawSyntaxNode{};
  }
};

} // end namespace swift

#endif
