//===-- ResourceScriptStmt.h ------------------------------------*- C++-*-===//
//
// 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
//
//===---------------------------------------------------------------------===//
//
// This lists all the resource and statement types occurring in RC scripts.
//
//===---------------------------------------------------------------------===//

#ifndef LLVM_TOOLS_LLVMRC_RESOURCESCRIPTSTMT_H
#define LLVM_TOOLS_LLVMRC_RESOURCESCRIPTSTMT_H

#include "ResourceScriptToken.h"
#include "ResourceVisitor.h"

#include "llvm/ADT/StringSet.h"

namespace llvm {
namespace rc {

// Integer wrapper that also holds information whether the user declared
// the integer to be long (by appending L to the end of the integer) or not.
// It allows to be implicitly cast from and to uint32_t in order
// to be compatible with the parts of code that don't care about the integers
// being marked long.
class RCInt {
  uint32_t Val;
  bool Long;

public:
  RCInt(const RCToken &Token)
      : Val(Token.intValue()), Long(Token.isLongInt()) {}
  RCInt(uint32_t Value) : Val(Value), Long(false) {}
  RCInt(uint32_t Value, bool IsLong) : Val(Value), Long(IsLong) {}
  operator uint32_t() const { return Val; }
  bool isLong() const { return Long; }

  RCInt &operator+=(const RCInt &Rhs) {
    std::tie(Val, Long) = std::make_pair(Val + Rhs.Val, Long | Rhs.Long);
    return *this;
  }

  RCInt &operator-=(const RCInt &Rhs) {
    std::tie(Val, Long) = std::make_pair(Val - Rhs.Val, Long | Rhs.Long);
    return *this;
  }

  RCInt &operator|=(const RCInt &Rhs) {
    std::tie(Val, Long) = std::make_pair(Val | Rhs.Val, Long | Rhs.Long);
    return *this;
  }

  RCInt &operator&=(const RCInt &Rhs) {
    std::tie(Val, Long) = std::make_pair(Val & Rhs.Val, Long | Rhs.Long);
    return *this;
  }

  RCInt operator-() const { return {-Val, Long}; }
  RCInt operator~() const { return {~Val, Long}; }

  friend raw_ostream &operator<<(raw_ostream &OS, const RCInt &Int) {
    return OS << Int.Val << (Int.Long ? "L" : "");
  }
};

class IntWithNotMask {
private:
  RCInt Value;
  int32_t NotMask;

public:
  IntWithNotMask() : IntWithNotMask(RCInt(0)) {}
  IntWithNotMask(RCInt Value, int32_t NotMask = 0) : Value(Value), NotMask(NotMask) {}

  RCInt getValue() const {
    return Value;
  }

  uint32_t getNotMask() const {
    return NotMask;
  }

  IntWithNotMask &operator+=(const IntWithNotMask &Rhs) {
    Value &= ~Rhs.NotMask;
    Value += Rhs.Value;
    NotMask |= Rhs.NotMask;
    return *this;
  }

  IntWithNotMask &operator-=(const IntWithNotMask &Rhs) {
    Value &= ~Rhs.NotMask;
    Value -= Rhs.Value;
    NotMask |= Rhs.NotMask;
    return *this;
  }

  IntWithNotMask &operator|=(const IntWithNotMask &Rhs) {
    Value &= ~Rhs.NotMask;
    Value |= Rhs.Value;
    NotMask |= Rhs.NotMask;
    return *this;
  }

  IntWithNotMask &operator&=(const IntWithNotMask &Rhs) {
    Value &= ~Rhs.NotMask;
    Value &= Rhs.Value;
    NotMask |= Rhs.NotMask;
    return *this;
  }

  IntWithNotMask operator-() const { return {-Value, NotMask}; }
  IntWithNotMask operator~() const { return {~Value, 0}; }

  friend raw_ostream &operator<<(raw_ostream &OS, const IntWithNotMask &Int) {
    return OS << Int.Value;
  }
};

// A class holding a name - either an integer or a reference to the string.
class IntOrString {
private:
  union Data {
    RCInt Int;
    StringRef String;
    Data(RCInt Value) : Int(Value) {}
    Data(const StringRef Value) : String(Value) {}
    Data(const RCToken &Token) {
      if (Token.kind() == RCToken::Kind::Int)
        Int = RCInt(Token);
      else
        String = Token.value();
    }
  } Data;
  bool IsInt;

public:
  IntOrString() : IntOrString(RCInt(0)) {}
  IntOrString(uint32_t Value) : Data(Value), IsInt(1) {}
  IntOrString(RCInt Value) : Data(Value), IsInt(1) {}
  IntOrString(StringRef Value) : Data(Value), IsInt(0) {}
  IntOrString(const RCToken &Token)
      : Data(Token), IsInt(Token.kind() == RCToken::Kind::Int) {}

  bool equalsLower(const char *Str) {
    return !IsInt && Data.String.equals_lower(Str);
  }

  bool isInt() const { return IsInt; }

  RCInt getInt() const {
    assert(IsInt);
    return Data.Int;
  }

  const StringRef &getString() const {
    assert(!IsInt);
    return Data.String;
  }

  operator Twine() const {
    return isInt() ? Twine(getInt()) : Twine(getString());
  }

  friend raw_ostream &operator<<(raw_ostream &, const IntOrString &);
};

enum ResourceKind {
  // These resource kinds have corresponding .res resource type IDs
  // (TYPE in RESOURCEHEADER structure). The numeric value assigned to each
  // kind is equal to this type ID.
  RkNull = 0,
  RkSingleCursor = 1,
  RkBitmap = 2,
  RkSingleIcon = 3,
  RkMenu = 4,
  RkDialog = 5,
  RkStringTableBundle = 6,
  RkAccelerators = 9,
  RkRcData = 10,
  RkCursorGroup = 12,
  RkIconGroup = 14,
  RkVersionInfo = 16,
  RkHTML = 23,

  // These kinds don't have assigned type IDs (they might be the resources
  // of invalid kind, expand to many resource structures in .res files,
  // or have variable type ID). In order to avoid ID clashes with IDs above,
  // we assign the kinds the values 256 and larger.
  RkInvalid = 256,
  RkBase,
  RkCursor,
  RkIcon,
  RkStringTable,
  RkUser,
  RkSingleCursorOrIconRes,
  RkCursorOrIconGroupRes,
};

// Non-zero memory flags.
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/ms648027(v=vs.85).aspx
enum MemoryFlags {
  MfMoveable = 0x10,
  MfPure = 0x20,
  MfPreload = 0x40,
  MfDiscardable = 0x1000
};

// Base resource. All the resources should derive from this base.
class RCResource {
public:
  IntOrString ResName;
  uint16_t MemoryFlags = getDefaultMemoryFlags();
  void setName(const IntOrString &Name) { ResName = Name; }
  virtual raw_ostream &log(raw_ostream &OS) const {
    return OS << "Base statement\n";
  };
  RCResource() {}
  RCResource(uint16_t Flags) : MemoryFlags(Flags) {}
  virtual ~RCResource() {}

  virtual Error visit(Visitor *) const {
    llvm_unreachable("This is unable to call methods from Visitor base");
  }

  // Apply the statements attached to this resource. Generic resources
  // don't have any.
  virtual Error applyStmts(Visitor *) const { return Error::success(); }

  // By default, memory flags are DISCARDABLE | PURE | MOVEABLE.
  static uint16_t getDefaultMemoryFlags() {
    return MfDiscardable | MfPure | MfMoveable;
  }

  virtual ResourceKind getKind() const { return RkBase; }
  static bool classof(const RCResource *Res) { return true; }

  virtual IntOrString getResourceType() const {
    llvm_unreachable("This cannot be called on objects without types.");
  }
  virtual Twine getResourceTypeName() const {
    llvm_unreachable("This cannot be called on objects without types.");
  };
};

// An empty resource. It has no content, type 0, ID 0 and all of its
// characteristics are equal to 0.
class NullResource : public RCResource {
public:
  NullResource() : RCResource(0) {}
  raw_ostream &log(raw_ostream &OS) const override {
    return OS << "Null resource\n";
  }
  Error visit(Visitor *V) const override { return V->visitNullResource(this); }
  IntOrString getResourceType() const override { return 0; }
  Twine getResourceTypeName() const override { return "(NULL)"; }
};

// Optional statement base. All such statements should derive from this base.
class OptionalStmt : public RCResource {};

class OptionalStmtList : public OptionalStmt {
  std::vector<std::unique_ptr<OptionalStmt>> Statements;

public:
  OptionalStmtList() {}
  raw_ostream &log(raw_ostream &OS) const override;

  void addStmt(std::unique_ptr<OptionalStmt> Stmt) {
    Statements.push_back(std::move(Stmt));
  }

  Error visit(Visitor *V) const override {
    for (auto &StmtPtr : Statements)
      if (auto Err = StmtPtr->visit(V))
        return Err;
    return Error::success();
  }
};

class OptStatementsRCResource : public RCResource {
public:
  std::unique_ptr<OptionalStmtList> OptStatements;

  OptStatementsRCResource(OptionalStmtList &&Stmts,
                          uint16_t Flags = RCResource::getDefaultMemoryFlags())
      : RCResource(Flags),
        OptStatements(std::make_unique<OptionalStmtList>(std::move(Stmts))) {}

  Error applyStmts(Visitor *V) const override {
    return OptStatements->visit(V);
  }
};

// LANGUAGE statement. It can occur both as a top-level statement (in such
// a situation, it changes the default language until the end of the file)
// and as an optional resource statement (then it changes the language
// of a single resource).
//
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381019(v=vs.85).aspx
class LanguageResource : public OptionalStmt {
public:
  uint32_t Lang, SubLang;

  LanguageResource(uint32_t LangId, uint32_t SubLangId)
      : Lang(LangId), SubLang(SubLangId) {}
  raw_ostream &log(raw_ostream &) const override;

  // This is not a regular top-level statement; when it occurs, it just
  // modifies the language context.
  Error visit(Visitor *V) const override { return V->visitLanguageStmt(this); }
  Twine getResourceTypeName() const override { return "LANGUAGE"; }
};

// ACCELERATORS resource. Defines a named table of accelerators for the app.
//
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380610(v=vs.85).aspx
class AcceleratorsResource : public OptStatementsRCResource {
public:
  class Accelerator {
  public:
    IntOrString Event;
    uint32_t Id;
    uint16_t Flags;

    enum Options {
      // This is actually 0x0000 (accelerator is assumed to be ASCII if it's
      // not VIRTKEY). However, rc.exe behavior is different in situations
      // "only ASCII defined" and "neither ASCII nor VIRTKEY defined".
      // Therefore, we include ASCII as another flag. This must be zeroed
      // when serialized.
      ASCII = 0x8000,
      VIRTKEY = 0x0001,
      NOINVERT = 0x0002,
      ALT = 0x0010,
      SHIFT = 0x0004,
      CONTROL = 0x0008
    };

    static constexpr size_t NumFlags = 6;
    static StringRef OptionsStr[NumFlags];
    static uint32_t OptionsFlags[NumFlags];
  };

  AcceleratorsResource(OptionalStmtList &&List, uint16_t Flags)
      : OptStatementsRCResource(std::move(List), Flags) {}

  std::vector<Accelerator> Accelerators;

  void addAccelerator(IntOrString Event, uint32_t Id, uint16_t Flags) {
    Accelerators.push_back(Accelerator{Event, Id, Flags});
  }
  raw_ostream &log(raw_ostream &) const override;

  IntOrString getResourceType() const override { return RkAccelerators; }
  static uint16_t getDefaultMemoryFlags() { return MfPure | MfMoveable; }
  Twine getResourceTypeName() const override { return "ACCELERATORS"; }

  Error visit(Visitor *V) const override {
    return V->visitAcceleratorsResource(this);
  }
  ResourceKind getKind() const override { return RkAccelerators; }
  static bool classof(const RCResource *Res) {
    return Res->getKind() == RkAccelerators;
  }
};

// BITMAP resource. Represents a bitmap (".bmp") file.
//
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380680(v=vs.85).aspx
class BitmapResource : public RCResource {
public:
  StringRef BitmapLoc;

  BitmapResource(StringRef Location, uint16_t Flags)
      : RCResource(Flags), BitmapLoc(Location) {}
  raw_ostream &log(raw_ostream &) const override;

  IntOrString getResourceType() const override { return RkBitmap; }
  static uint16_t getDefaultMemoryFlags() { return MfPure | MfMoveable; }

  Twine getResourceTypeName() const override { return "BITMAP"; }
  Error visit(Visitor *V) const override {
    return V->visitBitmapResource(this);
  }
  ResourceKind getKind() const override { return RkBitmap; }
  static bool classof(const RCResource *Res) {
    return Res->getKind() == RkBitmap;
  }
};

// CURSOR resource. Represents a single cursor (".cur") file.
//
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380920(v=vs.85).aspx
class CursorResource : public RCResource {
public:
  StringRef CursorLoc;

  CursorResource(StringRef Location, uint16_t Flags)
      : RCResource(Flags), CursorLoc(Location) {}
  raw_ostream &log(raw_ostream &) const override;

  Twine getResourceTypeName() const override { return "CURSOR"; }
  static uint16_t getDefaultMemoryFlags() { return MfDiscardable | MfMoveable; }
  Error visit(Visitor *V) const override {
    return V->visitCursorResource(this);
  }
  ResourceKind getKind() const override { return RkCursor; }
  static bool classof(const RCResource *Res) {
    return Res->getKind() == RkCursor;
  }
};

// ICON resource. Represents a single ".ico" file containing a group of icons.
//
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381018(v=vs.85).aspx
class IconResource : public RCResource {
public:
  StringRef IconLoc;

  IconResource(StringRef Location, uint16_t Flags)
      : RCResource(Flags), IconLoc(Location) {}
  raw_ostream &log(raw_ostream &) const override;

  Twine getResourceTypeName() const override { return "ICON"; }
  static uint16_t getDefaultMemoryFlags() { return MfDiscardable | MfMoveable; }
  Error visit(Visitor *V) const override { return V->visitIconResource(this); }
  ResourceKind getKind() const override { return RkIcon; }
  static bool classof(const RCResource *Res) {
    return Res->getKind() == RkIcon;
  }
};

// HTML resource. Represents a local webpage that is to be embedded into the
// resulting resource file. It embeds a file only - no additional resources
// (images etc.) are included with this resource.
//
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa966018(v=vs.85).aspx
class HTMLResource : public RCResource {
public:
  StringRef HTMLLoc;

  HTMLResource(StringRef Location, uint16_t Flags)
      : RCResource(Flags), HTMLLoc(Location) {}
  raw_ostream &log(raw_ostream &) const override;

  Error visit(Visitor *V) const override { return V->visitHTMLResource(this); }

  // Curiously, file resources don't have DISCARDABLE flag set.
  static uint16_t getDefaultMemoryFlags() { return MfPure | MfMoveable; }
  IntOrString getResourceType() const override { return RkHTML; }
  Twine getResourceTypeName() const override { return "HTML"; }
  ResourceKind getKind() const override { return RkHTML; }
  static bool classof(const RCResource *Res) {
    return Res->getKind() == RkHTML;
  }
};

// -- MENU resource and its helper classes --
// This resource describes the contents of an application menu
// (usually located in the upper part of the dialog.)
//
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381025(v=vs.85).aspx

// Description of a single submenu item.
class MenuDefinition {
public:
  enum Options {
    CHECKED = 0x0008,
    GRAYED = 0x0001,
    HELP = 0x4000,
    INACTIVE = 0x0002,
    MENUBARBREAK = 0x0020,
    MENUBREAK = 0x0040
  };

  enum MenuDefKind { MkBase, MkSeparator, MkMenuItem, MkPopup };

  static constexpr size_t NumFlags = 6;
  static StringRef OptionsStr[NumFlags];
  static uint32_t OptionsFlags[NumFlags];
  static raw_ostream &logFlags(raw_ostream &, uint16_t Flags);
  virtual raw_ostream &log(raw_ostream &OS) const {
    return OS << "Base menu definition\n";
  }
  virtual ~MenuDefinition() {}

  virtual uint16_t getResFlags() const { return 0; }
  virtual MenuDefKind getKind() const { return MkBase; }
};

// Recursive description of a whole submenu.
class MenuDefinitionList : public MenuDefinition {
public:
  std::vector<std::unique_ptr<MenuDefinition>> Definitions;

  void addDefinition(std::unique_ptr<MenuDefinition> Def) {
    Definitions.push_back(std::move(Def));
  }
  raw_ostream &log(raw_ostream &) const override;
};

// Separator in MENU definition (MENUITEM SEPARATOR).
//
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381024(v=vs.85).aspx
class MenuSeparator : public MenuDefinition {
public:
  raw_ostream &log(raw_ostream &) const override;

  MenuDefKind getKind() const override { return MkSeparator; }
  static bool classof(const MenuDefinition *D) {
    return D->getKind() == MkSeparator;
  }
};

// MENUITEM statement definition.
//
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381024(v=vs.85).aspx
class MenuItem : public MenuDefinition {
public:
  StringRef Name;
  uint32_t Id;
  uint16_t Flags;

  MenuItem(StringRef Caption, uint32_t ItemId, uint16_t ItemFlags)
      : Name(Caption), Id(ItemId), Flags(ItemFlags) {}
  raw_ostream &log(raw_ostream &) const override;

  uint16_t getResFlags() const override { return Flags; }
  MenuDefKind getKind() const override { return MkMenuItem; }
  static bool classof(const MenuDefinition *D) {
    return D->getKind() == MkMenuItem;
  }
};

// POPUP statement definition.
//
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381030(v=vs.85).aspx
class PopupItem : public MenuDefinition {
public:
  StringRef Name;
  uint16_t Flags;
  MenuDefinitionList SubItems;

  PopupItem(StringRef Caption, uint16_t ItemFlags,
            MenuDefinitionList &&SubItemsList)
      : Name(Caption), Flags(ItemFlags), SubItems(std::move(SubItemsList)) {}
  raw_ostream &log(raw_ostream &) const override;

  // This has an additional (0x10) flag. It doesn't match with documented
  // 0x01 flag, though.
  uint16_t getResFlags() const override { return Flags | 0x10; }
  MenuDefKind getKind() const override { return MkPopup; }
  static bool classof(const MenuDefinition *D) {
    return D->getKind() == MkPopup;
  }
};

// Menu resource definition.
class MenuResource : public OptStatementsRCResource {
public:
  MenuDefinitionList Elements;

  MenuResource(OptionalStmtList &&OptStmts, MenuDefinitionList &&Items,
               uint16_t Flags)
      : OptStatementsRCResource(std::move(OptStmts), Flags),
        Elements(std::move(Items)) {}
  raw_ostream &log(raw_ostream &) const override;

  IntOrString getResourceType() const override { return RkMenu; }
  Twine getResourceTypeName() const override { return "MENU"; }
  Error visit(Visitor *V) const override { return V->visitMenuResource(this); }
  ResourceKind getKind() const override { return RkMenu; }
  static bool classof(const RCResource *Res) {
    return Res->getKind() == RkMenu;
  }
};

// STRINGTABLE resource. Contains a list of strings, each having its unique ID.
//
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381050(v=vs.85).aspx
class StringTableResource : public OptStatementsRCResource {
public:
  std::vector<std::pair<uint32_t, std::vector<StringRef>>> Table;

  StringTableResource(OptionalStmtList &&List, uint16_t Flags)
      : OptStatementsRCResource(std::move(List), Flags) {}
  void addStrings(uint32_t ID, std::vector<StringRef> &&Strings) {
    Table.emplace_back(ID, Strings);
  }
  raw_ostream &log(raw_ostream &) const override;
  Twine getResourceTypeName() const override { return "STRINGTABLE"; }
  Error visit(Visitor *V) const override {
    return V->visitStringTableResource(this);
  }
};

// -- DIALOG(EX) resource and its helper classes --
//
// This resource describes dialog boxes and controls residing inside them.
//
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381003(v=vs.85).aspx
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381002(v=vs.85).aspx

// Single control definition.
class Control {
public:
  StringRef Type;
  IntOrString Title;
  uint32_t ID, X, Y, Width, Height;
  Optional<IntWithNotMask> Style;
  Optional<uint32_t> ExtStyle, HelpID;
  IntOrString Class;

  // Control classes as described in DLGITEMTEMPLATEEX documentation.
  //
  // Ref: msdn.microsoft.com/en-us/library/windows/desktop/ms645389.aspx
  enum CtlClasses {
    ClsButton = 0x80,
    ClsEdit = 0x81,
    ClsStatic = 0x82,
    ClsListBox = 0x83,
    ClsScrollBar = 0x84,
    ClsComboBox = 0x85
  };

  // Simple information about a single control type.
  struct CtlInfo {
    uint32_t Style;
    uint16_t CtlClass;
    bool HasTitle;
  };

  Control(StringRef CtlType, IntOrString CtlTitle, uint32_t CtlID,
          uint32_t PosX, uint32_t PosY, uint32_t ItemWidth, uint32_t ItemHeight,
          Optional<IntWithNotMask> ItemStyle, Optional<uint32_t> ExtItemStyle,
          Optional<uint32_t> CtlHelpID, IntOrString CtlClass)
      : Type(CtlType), Title(CtlTitle), ID(CtlID), X(PosX), Y(PosY),
        Width(ItemWidth), Height(ItemHeight), Style(ItemStyle),
        ExtStyle(ExtItemStyle), HelpID(CtlHelpID), Class(CtlClass) {}

  static const StringMap<CtlInfo> SupportedCtls;

  raw_ostream &log(raw_ostream &) const;
};

// Single dialog definition. We don't create distinct classes for DIALOG and
// DIALOGEX because of their being too similar to each other. We only have a
// flag determining the type of the dialog box.
class DialogResource : public OptStatementsRCResource {
public:
  uint32_t X, Y, Width, Height, HelpID;
  std::vector<Control> Controls;
  bool IsExtended;

  DialogResource(uint32_t PosX, uint32_t PosY, uint32_t DlgWidth,
                 uint32_t DlgHeight, uint32_t DlgHelpID,
                 OptionalStmtList &&OptStmts, bool IsDialogEx, uint16_t Flags)
      : OptStatementsRCResource(std::move(OptStmts), Flags), X(PosX), Y(PosY),
        Width(DlgWidth), Height(DlgHeight), HelpID(DlgHelpID),
        IsExtended(IsDialogEx) {}

  void addControl(Control &&Ctl) { Controls.push_back(std::move(Ctl)); }

  raw_ostream &log(raw_ostream &) const override;

  // It was a weird design decision to assign the same resource type number
  // both for DIALOG and DIALOGEX (and the same structure version number).
  // It makes it possible for DIALOG to be mistaken for DIALOGEX.
  IntOrString getResourceType() const override { return RkDialog; }
  Twine getResourceTypeName() const override {
    return "DIALOG" + Twine(IsExtended ? "EX" : "");
  }
  Error visit(Visitor *V) const override {
    return V->visitDialogResource(this);
  }
  ResourceKind getKind() const override { return RkDialog; }
  static bool classof(const RCResource *Res) {
    return Res->getKind() == RkDialog;
  }
};

// User-defined resource. It is either:
//   * a link to the file, e.g. NAME TYPE "filename",
//   * or contains a list of integers and strings, e.g. NAME TYPE {1, "a", 2}.
class UserDefinedResource : public RCResource {
public:
  IntOrString Type;
  StringRef FileLoc;
  std::vector<IntOrString> Contents;
  bool IsFileResource;

  UserDefinedResource(IntOrString ResourceType, StringRef FileLocation,
                      uint16_t Flags)
      : RCResource(Flags), Type(ResourceType), FileLoc(FileLocation),
        IsFileResource(true) {}
  UserDefinedResource(IntOrString ResourceType, std::vector<IntOrString> &&Data,
                      uint16_t Flags)
      : RCResource(Flags), Type(ResourceType), Contents(std::move(Data)),
        IsFileResource(false) {}

  raw_ostream &log(raw_ostream &) const override;
  IntOrString getResourceType() const override { return Type; }
  Twine getResourceTypeName() const override { return Type; }
  static uint16_t getDefaultMemoryFlags() { return MfPure | MfMoveable; }

  Error visit(Visitor *V) const override {
    return V->visitUserDefinedResource(this);
  }
  ResourceKind getKind() const override { return RkUser; }
  static bool classof(const RCResource *Res) {
    return Res->getKind() == RkUser;
  }
};

// -- VERSIONINFO resource and its helper classes --
//
// This resource lists the version information on the executable/library.
// The declaration consists of the following items:
//   * A number of fixed optional version statements (e.g. FILEVERSION, FILEOS)
//   * BEGIN
//   * A number of BLOCK and/or VALUE statements. BLOCK recursively defines
//       another block of version information, whereas VALUE defines a
//       key -> value correspondence. There might be more than one value
//       corresponding to the single key.
//   * END
//
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381058(v=vs.85).aspx

// A single VERSIONINFO statement;
class VersionInfoStmt {
public:
  enum StmtKind { StBase = 0, StBlock = 1, StValue = 2 };

  virtual raw_ostream &log(raw_ostream &OS) const { return OS << "VI stmt\n"; }
  virtual ~VersionInfoStmt() {}

  virtual StmtKind getKind() const { return StBase; }
  static bool classof(const VersionInfoStmt *S) {
    return S->getKind() == StBase;
  }
};

// BLOCK definition; also the main VERSIONINFO declaration is considered a
// BLOCK, although it has no name.
// The correct top-level blocks are "VarFileInfo" and "StringFileInfo". We don't
// care about them at the parsing phase.
class VersionInfoBlock : public VersionInfoStmt {
public:
  std::vector<std::unique_ptr<VersionInfoStmt>> Stmts;
  StringRef Name;

  VersionInfoBlock(StringRef BlockName) : Name(BlockName) {}
  void addStmt(std::unique_ptr<VersionInfoStmt> Stmt) {
    Stmts.push_back(std::move(Stmt));
  }
  raw_ostream &log(raw_ostream &) const override;

  StmtKind getKind() const override { return StBlock; }
  static bool classof(const VersionInfoStmt *S) {
    return S->getKind() == StBlock;
  }
};

class VersionInfoValue : public VersionInfoStmt {
public:
  StringRef Key;
  std::vector<IntOrString> Values;
  std::vector<bool> HasPrecedingComma;

  VersionInfoValue(StringRef InfoKey, std::vector<IntOrString> &&Vals,
                   std::vector<bool> &&CommasBeforeVals)
      : Key(InfoKey), Values(std::move(Vals)),
        HasPrecedingComma(std::move(CommasBeforeVals)) {}
  raw_ostream &log(raw_ostream &) const override;

  StmtKind getKind() const override { return StValue; }
  static bool classof(const VersionInfoStmt *S) {
    return S->getKind() == StValue;
  }
};

class VersionInfoResource : public RCResource {
public:
  // A class listing fixed VERSIONINFO statements (occuring before main BEGIN).
  // If any of these is not specified, it is assumed by the original tool to
  // be equal to 0.
  class VersionInfoFixed {
  public:
    enum VersionInfoFixedType {
      FtUnknown,
      FtFileVersion,
      FtProductVersion,
      FtFileFlagsMask,
      FtFileFlags,
      FtFileOS,
      FtFileType,
      FtFileSubtype,
      FtNumTypes
    };

  private:
    static const StringMap<VersionInfoFixedType> FixedFieldsInfoMap;
    static const StringRef FixedFieldsNames[FtNumTypes];

  public:
    SmallVector<uint32_t, 4> FixedInfo[FtNumTypes];
    SmallVector<bool, FtNumTypes> IsTypePresent;

    static VersionInfoFixedType getFixedType(StringRef Type);
    static bool isTypeSupported(VersionInfoFixedType Type);
    static bool isVersionType(VersionInfoFixedType Type);

    VersionInfoFixed() : IsTypePresent(FtNumTypes, false) {}

    void setValue(VersionInfoFixedType Type, ArrayRef<uint32_t> Value) {
      FixedInfo[Type] = SmallVector<uint32_t, 4>(Value.begin(), Value.end());
      IsTypePresent[Type] = true;
    }

    raw_ostream &log(raw_ostream &) const;
  };

  VersionInfoBlock MainBlock;
  VersionInfoFixed FixedData;

  VersionInfoResource(VersionInfoBlock &&TopLevelBlock,
                      VersionInfoFixed &&FixedInfo, uint16_t Flags)
      : RCResource(Flags), MainBlock(std::move(TopLevelBlock)),
        FixedData(std::move(FixedInfo)) {}

  raw_ostream &log(raw_ostream &) const override;
  IntOrString getResourceType() const override { return RkVersionInfo; }
  static uint16_t getDefaultMemoryFlags() { return MfMoveable | MfPure; }
  Twine getResourceTypeName() const override { return "VERSIONINFO"; }
  Error visit(Visitor *V) const override {
    return V->visitVersionInfoResource(this);
  }
  ResourceKind getKind() const override { return RkVersionInfo; }
  static bool classof(const RCResource *Res) {
    return Res->getKind() == RkVersionInfo;
  }
};

// CHARACTERISTICS optional statement.
//
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380872(v=vs.85).aspx
class CharacteristicsStmt : public OptionalStmt {
public:
  uint32_t Value;

  CharacteristicsStmt(uint32_t Characteristic) : Value(Characteristic) {}
  raw_ostream &log(raw_ostream &) const override;

  Twine getResourceTypeName() const override { return "CHARACTERISTICS"; }
  Error visit(Visitor *V) const override {
    return V->visitCharacteristicsStmt(this);
  }
};

// VERSION optional statement.
//
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381059(v=vs.85).aspx
class VersionStmt : public OptionalStmt {
public:
  uint32_t Value;

  VersionStmt(uint32_t Version) : Value(Version) {}
  raw_ostream &log(raw_ostream &) const override;

  Twine getResourceTypeName() const override { return "VERSION"; }
  Error visit(Visitor *V) const override { return V->visitVersionStmt(this); }
};

// CAPTION optional statement.
//
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380778(v=vs.85).aspx
class CaptionStmt : public OptionalStmt {
public:
  StringRef Value;

  CaptionStmt(StringRef Caption) : Value(Caption) {}
  raw_ostream &log(raw_ostream &) const override;
  Twine getResourceTypeName() const override { return "CAPTION"; }
  Error visit(Visitor *V) const override { return V->visitCaptionStmt(this); }
};

// FONT optional statement.
// Note that the documentation is inaccurate: it expects five arguments to be
// given, however the example provides only two. In fact, the original tool
// expects two arguments - point size and name of the typeface.
//
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381013(v=vs.85).aspx
class FontStmt : public OptionalStmt {
public:
  uint32_t Size, Weight, Charset;
  StringRef Name;
  bool Italic;

  FontStmt(uint32_t FontSize, StringRef FontName, uint32_t FontWeight,
           bool FontItalic, uint32_t FontCharset)
      : Size(FontSize), Weight(FontWeight), Charset(FontCharset),
        Name(FontName), Italic(FontItalic) {}
  raw_ostream &log(raw_ostream &) const override;
  Twine getResourceTypeName() const override { return "FONT"; }
  Error visit(Visitor *V) const override { return V->visitFontStmt(this); }
};

// STYLE optional statement.
//
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381051(v=vs.85).aspx
class StyleStmt : public OptionalStmt {
public:
  uint32_t Value;

  StyleStmt(uint32_t Style) : Value(Style) {}
  raw_ostream &log(raw_ostream &) const override;
  Twine getResourceTypeName() const override { return "STYLE"; }
  Error visit(Visitor *V) const override { return V->visitStyleStmt(this); }
};

// EXSTYLE optional statement.
//
// Ref: docs.microsoft.com/en-us/windows/desktop/menurc/exstyle-statement
class ExStyleStmt : public OptionalStmt {
public:
  uint32_t Value;

  ExStyleStmt(uint32_t ExStyle) : Value(ExStyle) {}
  raw_ostream &log(raw_ostream &) const override;
  Twine getResourceTypeName() const override { return "EXSTYLE"; }
  Error visit(Visitor *V) const override { return V->visitExStyleStmt(this); }
};

// CLASS optional statement.
//
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380883(v=vs.85).aspx
class ClassStmt : public OptionalStmt {
public:
  IntOrString Value;

  ClassStmt(IntOrString Class) : Value(Class) {}
  raw_ostream &log(raw_ostream &) const override;
  Twine getResourceTypeName() const override { return "CLASS"; }
  Error visit(Visitor *V) const override { return V->visitClassStmt(this); }
};

} // namespace rc
} // namespace llvm

#endif
