/*
 Do not modify, auto-generated by classes.py

 Copyright 2019 Alain Dargelas

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

/*
 * File:   variables.h
 * Author:
 *
 * Created on December 14, 2019, 10:03 PM
 */

#ifndef UHDM_VARIABLES_H
#define UHDM_VARIABLES_H

#include <uhdm/sv_vpi_user.h>
#include <uhdm/uhdm_vpi_user.h>

#include <uhdm/containers.h>
#include <uhdm/simple_expr.h>

#include "variable_drivers_group.h"
#include "variable_loads_group.h"


namespace UHDM {
class expr;
class instance;
class module_inst;
class path_term;
class scope;
class tchk_term;

class variables : public simple_expr {
  UHDM_IMPLEMENT_RTTI(variables, simple_expr)
public:
  // Implicit constructor used to initialize all members,
  // comment: variables();
  virtual ~variables() = default;

  bool VpiArrayMember() const { return vpiArrayMember_; }
  bool VpiArrayMember(bool data) {
    vpiArrayMember_ = data;
    return true;
  }

  virtual bool VpiName(std::string_view data) final;
  virtual std::string_view VpiName() const final;

  bool VpiFullName(std::string_view data);
  std::string_view VpiFullName() const;

  bool VpiSigned() const { return vpiSigned_; }
  bool VpiSigned(bool data) {
    vpiSigned_ = data;
    return true;
  }

  bool VpiAutomatic() const { return vpiAutomatic_; }
  bool VpiAutomatic(bool data) {
    vpiAutomatic_ = data;
    return true;
  }

  int32_t VpiAllocScheme() const { return vpiAllocScheme_; }
  bool VpiAllocScheme(int32_t data) {
    vpiAllocScheme_ = data;
    return true;
  }

  bool VpiConstantVariable() const { return vpiConstantVariable_; }
  bool VpiConstantVariable(bool data) {
    vpiConstantVariable_ = data;
    return true;
  }

  bool VpiIsRandomized() const { return vpiIsRandomized_; }
  bool VpiIsRandomized(bool data) {
    vpiIsRandomized_ = data;
    return true;
  }

  int32_t VpiRandType() const { return vpiRandType_; }
  bool VpiRandType(int32_t data) {
    vpiRandType_ = data;
    return true;
  }

  bool VpiStructUnionMember() const { return vpiStructUnionMember_; }
  bool VpiStructUnionMember(bool data) {
    vpiStructUnionMember_ = data;
    return true;
  }

  bool VpiScalar() const { return vpiScalar_; }
  bool VpiScalar(bool data) {
    vpiScalar_ = data;
    return true;
  }

  int32_t VpiVisibility() const { return vpiVisibility_; }
  bool VpiVisibility(int32_t data) {
    vpiVisibility_ = data;
    return true;
  }

  bool VpiVector() const { return vpiVector_; }
  bool VpiVector(bool data) {
    vpiVector_ = data;
    return true;
  }

  VectorOfports* Ports() const { return ports_; }
  bool Ports(VectorOfports* data) {
    ports_ = data;
    return true;
  }

  VectorOfany* Variable_drivers() const { return variable_drivers_; }
  bool Variable_drivers(VectorOfany* data) {
    if (!variable_drivers_groupGroupCompliant(data)) return false;
    variable_drivers_ = data;
    return true;
  }

  VectorOfany* Variable_loads() const { return variable_loads_; }
  bool Variable_loads(VectorOfany* data) {
    if (!variable_loads_groupGroupCompliant(data)) return false;
    variable_loads_ = data;
    return true;
  }

  VectorOfprim_term* Prim_terms() const { return prim_terms_; }
  bool Prim_terms(VectorOfprim_term* data) {
    prim_terms_ = data;
    return true;
  }

  VectorOfcont_assign* Cont_assigns() const { return cont_assigns_; }
  bool Cont_assigns(VectorOfcont_assign* data) {
    cont_assigns_ = data;
    return true;
  }

  path_term* Path_term()  { return path_term_; }
  const path_term* Path_term() const { return path_term_; }
  template <typename T>
  T* Path_term() {
    return (path_term_ == nullptr) ? nullptr : any_cast<T*>(path_term_);
  }
  template <typename T>
  const T* Path_term() const {
    return (path_term_ == nullptr) ? nullptr : any_cast<const T*>(path_term_);
  }
  bool Path_term(path_term* data) {
    path_term_ = data;
    return true;
  }

  tchk_term* Tchk_term()  { return tchk_term_; }
  const tchk_term* Tchk_term() const { return tchk_term_; }
  template <typename T>
  T* Tchk_term() {
    return (tchk_term_ == nullptr) ? nullptr : any_cast<T*>(tchk_term_);
  }
  template <typename T>
  const T* Tchk_term() const {
    return (tchk_term_ == nullptr) ? nullptr : any_cast<const T*>(tchk_term_);
  }
  bool Tchk_term(tchk_term* data) {
    tchk_term_ = data;
    return true;
  }

  module_inst* Module_inst()  { return module_inst_; }
  const module_inst* Module_inst() const { return module_inst_; }
  template <typename T>
  T* Module_inst() {
    return (module_inst_ == nullptr) ? nullptr : any_cast<T*>(module_inst_);
  }
  template <typename T>
  const T* Module_inst() const {
    return (module_inst_ == nullptr) ? nullptr : any_cast<const T*>(module_inst_);
  }
  bool Module_inst(module_inst* data) {
    module_inst_ = data;
    return true;
  }

  instance* Instance()  { return instance_; }
  const instance* Instance() const { return instance_; }
  template <typename T>
  T* Instance() {
    return (instance_ == nullptr) ? nullptr : any_cast<T*>(instance_);
  }
  template <typename T>
  const T* Instance() const {
    return (instance_ == nullptr) ? nullptr : any_cast<const T*>(instance_);
  }
  bool Instance(instance* data) {
    instance_ = data;
    return true;
  }

  scope* Scope()  { return scope_; }
  const scope* Scope() const { return scope_; }
  template <typename T>
  T* Scope() {
    return (scope_ == nullptr) ? nullptr : any_cast<T*>(scope_);
  }
  template <typename T>
  const T* Scope() const {
    return (scope_ == nullptr) ? nullptr : any_cast<const T*>(scope_);
  }
  bool Scope(scope* data) {
    scope_ = data;
    return true;
  }

  expr* Expr()  { return expr_; }
  const expr* Expr() const { return expr_; }
  template <typename T>
  T* Expr() {
    return (expr_ == nullptr) ? nullptr : any_cast<T*>(expr_);
  }
  template <typename T>
  const T* Expr() const {
    return (expr_ == nullptr) ? nullptr : any_cast<const T*>(expr_);
  }
  bool Expr(expr* data) {
    expr_ = data;
    return true;
  }

  VectorOfexpr* Indexes() const { return indexes_; }
  bool Indexes(VectorOfexpr* data) {
    indexes_ = data;
    return true;
  }

  VectorOfattribute* Attributes() const { return attributes_; }
  bool Attributes(VectorOfattribute* data) {
    attributes_ = data;
    return true;
  }

  virtual variables* DeepClone(BaseClass* parent, CloneContext* context) const override = 0;

  virtual const BaseClass* GetByVpiName(std::string_view name) const override;

  virtual std::tuple<const BaseClass*, UHDM_OBJECT_TYPE, const std::vector<const BaseClass*>*> GetByVpiType(int32_t type) const override;

  virtual vpi_property_value_t GetVpiPropertyValue(int32_t property) const override;

  virtual int32_t Compare(const BaseClass* other, CompareContext* context) const override;

  virtual  UHDM_OBJECT_TYPE UhdmType() const override { return UHDM_OBJECT_TYPE::uhdmvariables; }

protected:
  void DeepCopy(variables* clone, BaseClass* parent, CloneContext* context) const;

private:
  bool vpiArrayMember_ = false;

  SymbolId vpiName_;

  SymbolId vpiFullName_;

  bool vpiSigned_ = false;

  bool vpiAutomatic_ = false;

  int32_t vpiAllocScheme_ = 0;

  bool vpiConstantVariable_ = false;

  bool vpiIsRandomized_ = false;

  int32_t vpiRandType_ = 0;

  bool vpiStructUnionMember_ = false;

  bool vpiScalar_ = false;

  int32_t vpiVisibility_ = 0;

  bool vpiVector_ = false;

  VectorOfports* ports_ = nullptr;

  VectorOfany* variable_drivers_ = nullptr;

  VectorOfany* variable_loads_ = nullptr;

  VectorOfprim_term* prim_terms_ = nullptr;

  VectorOfcont_assign* cont_assigns_ = nullptr;

  path_term* path_term_ = nullptr;

  tchk_term* tchk_term_ = nullptr;

  module_inst* module_inst_ = nullptr;

  instance* instance_ = nullptr;

  scope* scope_ = nullptr;

  expr* expr_ = nullptr;

  VectorOfexpr* indexes_ = nullptr;

  VectorOfattribute* attributes_ = nullptr;
};

#if 0 // This class cannot be instantiated
typedef FactoryT<variables> variablesFactory;
#endif

typedef FactoryT<std::vector<variables *>> VectorOfvariablesFactory;

}  // namespace UHDM

#endif
