//==--- AbstractBasicWriter.h - Abstract basic value serialization --------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef CLANG_AST_ABSTRACTBASICWRITER_H
#define CLANG_AST_ABSTRACTBASICWRITER_H

#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclTemplate.h"

namespace clang {
namespace serialization {

template <class T>
inline llvm::Optional<T> makeOptionalFromNullable(const T &value) {
  return (value.isNull()
            ? llvm::Optional<T>()
            : llvm::Optional<T>(value));
}

template <class T>
inline llvm::Optional<T*> makeOptionalFromPointer(T *value) {
  return (value ? llvm::Optional<T*>(value) : llvm::Optional<T*>());
}

// PropertyWriter is a class concept that requires the following method:
//   BasicWriter find(llvm::StringRef propertyName);
// where BasicWriter is some class conforming to the BasicWriter concept.
// An abstract AST-node writer is created with a PropertyWriter and
// performs a sequence of calls like so:
//   propertyWriter.find(propertyName).write##TypeName(value)
// to write the properties of the node it is serializing.

// BasicWriter is a class concept that requires methods like:
//   void write##TypeName(ValueType value);
// where TypeName is the name of a PropertyType node from PropertiesBase.td
// and ValueType is the corresponding C++ type name.
//
// In addition to the concrete property types, BasicWriter is expected
// to implement these methods:
//
//   template <class EnumType>
//   void writeEnum(T value);
//
//     Writes an enum value as the current property.  EnumType will always
//     be an enum type.  Only necessary if the BasicWriter doesn't provide
//     type-specific writers for all the enum types.
//
//   template <class ValueType>
//   void writeOptional(Optional<ValueType> value);
//
//     Writes an optional value as the current property.
//
//   template <class ValueType>
//   void writeArray(ArrayRef<ValueType> value);
//
//     Writes an array of values as the current property.
//
//   PropertyWriter writeObject();
//
//     Writes an object as the current property; the returned property
//     writer will be subjected to a sequence of property writes and then
//     discarded before any other properties are written to the "outer"
//     property writer (which need not be the same type).  The sub-writer
//     will be used as if with the following code:
//
//       {
//         auto &&widget = W.find("widget").writeObject();
//         widget.find("kind").writeWidgetKind(...);
//         widget.find("declaration").writeDeclRef(...);
//       }

// WriteDispatcher is a template which does type-based forwarding to one
// of the write methods of the BasicWriter passed in:
//
// template <class ValueType>
// struct WriteDispatcher {
//   template <class BasicWriter>
//   static void write(BasicWriter &W, ValueType value);
// };

// BasicWriterBase provides convenience implementations of the write
// methods for EnumPropertyType and SubclassPropertyType types that just
// defer to the "underlying" implementations (for UInt32 and the base class,
// respectively).
//
// template <class Impl>
// class BasicWriterBase {
// protected:
//   Impl &asImpl();
// public:
//   ...
// };

// The actual classes are auto-generated; see ClangASTPropertiesEmitter.cpp.
#include "clang/AST/AbstractBasicWriter.inc"

/// DataStreamBasicWriter provides convenience implementations for many
/// BasicWriter methods based on the assumption that the
/// ultimate writer implementation is based on a variable-length stream
/// of unstructured data (like Clang's module files).  It is designed
/// to pair with DataStreamBasicReader.
///
/// This class can also act as a PropertyWriter, implementing find("...")
/// by simply forwarding to itself.
///
/// Unimplemented methods:
///   writeBool
///   writeUInt32
///   writeUInt64
///   writeIdentifier
///   writeSelector
///   writeSourceLocation
///   writeQualType
///   writeStmtRef
///   writeDeclRef
template <class Impl>
class DataStreamBasicWriter : public BasicWriterBase<Impl> {
protected:
  using BasicWriterBase<Impl>::asImpl;
  DataStreamBasicWriter(ASTContext &ctx) : BasicWriterBase<Impl>(ctx) {}

public:
  /// Implement property-find by ignoring it.  We rely on properties being
  /// serialized and deserialized in a reliable order instead.
  Impl &find(const char *propertyName) {
    return asImpl();
  }

  // Implement object writing by forwarding to this, collapsing the
  // structure into a single data stream.
  Impl &writeObject() { return asImpl(); }

  template <class T>
  void writeEnum(T value) {
    asImpl().writeUInt32(uint32_t(value));
  }

  template <class T>
  void writeArray(llvm::ArrayRef<T> array) {
    asImpl().writeUInt32(array.size());
    for (const T &elt : array) {
      WriteDispatcher<T>::write(asImpl(), elt);
    }
  }

  template <class T>
  void writeOptional(llvm::Optional<T> value) {
    WriteDispatcher<T>::write(asImpl(), PackOptionalValue<T>::pack(value));
  }

  void writeAPSInt(const llvm::APSInt &value) {
    asImpl().writeBool(value.isUnsigned());
    asImpl().writeAPInt(value);
  }

  void writeAPInt(const llvm::APInt &value) {
    asImpl().writeUInt32(value.getBitWidth());
    const uint64_t *words = value.getRawData();
    for (size_t i = 0, e = value.getNumWords(); i != e; ++i)
      asImpl().writeUInt64(words[i]);
  }

  void writeFixedPointSemantics(const llvm::FixedPointSemantics &sema) {
    asImpl().writeUInt32(sema.getWidth());
    asImpl().writeUInt32(sema.getScale());
    asImpl().writeUInt32(sema.isSigned() | sema.isSaturated() << 1 |
                         sema.hasUnsignedPadding() << 2);
  }

  void writeLValuePathSerializationHelper(
      APValue::LValuePathSerializationHelper lvaluePath) {
    ArrayRef<APValue::LValuePathEntry> path = lvaluePath.Path;
    QualType elemTy = lvaluePath.getType();
    asImpl().writeQualType(elemTy);
    asImpl().writeUInt32(path.size());
    auto &ctx = ((BasicWriterBase<Impl> *)this)->getASTContext();
    for (auto elem : path) {
      if (elemTy->getAs<RecordType>()) {
        asImpl().writeUInt32(elem.getAsBaseOrMember().getInt());
        const Decl *baseOrMember = elem.getAsBaseOrMember().getPointer();
        if (const auto *recordDecl = dyn_cast<CXXRecordDecl>(baseOrMember)) {
          asImpl().writeDeclRef(recordDecl);
          elemTy = ctx.getRecordType(recordDecl);
        } else {
          const auto *valueDecl = cast<ValueDecl>(baseOrMember);
          asImpl().writeDeclRef(valueDecl);
          elemTy = valueDecl->getType();
        }
      } else {
        asImpl().writeUInt32(elem.getAsArrayIndex());
        elemTy = ctx.getAsArrayType(elemTy)->getElementType();
      }
    }
  }

  void writeQualifiers(Qualifiers value) {
    static_assert(sizeof(value.getAsOpaqueValue()) <= sizeof(uint32_t),
                  "update this if the value size changes");
    asImpl().writeUInt32(value.getAsOpaqueValue());
  }

  void writeExceptionSpecInfo(
                        const FunctionProtoType::ExceptionSpecInfo &esi) {
    asImpl().writeUInt32(uint32_t(esi.Type));
    if (esi.Type == EST_Dynamic) {
      asImpl().writeArray(esi.Exceptions);
    } else if (isComputedNoexcept(esi.Type)) {
      asImpl().writeExprRef(esi.NoexceptExpr);
    } else if (esi.Type == EST_Uninstantiated) {
      asImpl().writeDeclRef(esi.SourceDecl);
      asImpl().writeDeclRef(esi.SourceTemplate);
    } else if (esi.Type == EST_Unevaluated) {
      asImpl().writeDeclRef(esi.SourceDecl);
    }
  }

  void writeExtParameterInfo(FunctionProtoType::ExtParameterInfo epi) {
    static_assert(sizeof(epi.getOpaqueValue()) <= sizeof(uint32_t),
                  "opaque value doesn't fit into uint32_t");
    asImpl().writeUInt32(epi.getOpaqueValue());
  }

  void writeNestedNameSpecifier(NestedNameSpecifier *NNS) {
    // Nested name specifiers usually aren't too long. I think that 8 would
    // typically accommodate the vast majority.
    SmallVector<NestedNameSpecifier *, 8> nestedNames;

    // Push each of the NNS's onto a stack for serialization in reverse order.
    while (NNS) {
      nestedNames.push_back(NNS);
      NNS = NNS->getPrefix();
    }

    asImpl().writeUInt32(nestedNames.size());
    while (!nestedNames.empty()) {
      NNS = nestedNames.pop_back_val();
      NestedNameSpecifier::SpecifierKind kind = NNS->getKind();
      asImpl().writeNestedNameSpecifierKind(kind);
      switch (kind) {
      case NestedNameSpecifier::Identifier:
        asImpl().writeIdentifier(NNS->getAsIdentifier());
        continue;

      case NestedNameSpecifier::Namespace:
        asImpl().writeNamespaceDeclRef(NNS->getAsNamespace());
        continue;

      case NestedNameSpecifier::NamespaceAlias:
        asImpl().writeNamespaceAliasDeclRef(NNS->getAsNamespaceAlias());
        continue;

      case NestedNameSpecifier::TypeSpec:
      case NestedNameSpecifier::TypeSpecWithTemplate:
        asImpl().writeQualType(QualType(NNS->getAsType(), 0));
        continue;

      case NestedNameSpecifier::Global:
        // Don't need to write an associated value.
        continue;

      case NestedNameSpecifier::Super:
        asImpl().writeDeclRef(NNS->getAsRecordDecl());
        continue;
      }
      llvm_unreachable("bad nested name specifier kind");
    }
  }
};

} // end namespace serialization
} // end namespace clang

#endif
