// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_LIB_FIDL_CODEC_VISITOR_H_
#define SRC_LIB_FIDL_CODEC_VISITOR_H_

#include "src/lib/fidl_codec/wire_object.h"
#include "src/lib/fidl_codec/wire_types.h"

namespace fidl_codec {

// Superclass for implementing visitors for Values. Note that the whole class is protected. To use a
// visitor, use the Visit method on the Value object you want to visit.
class Visitor {
 protected:
  virtual void VisitValue(const Value* node, const Type* for_type) {}
  virtual void VisitInvalidValue(const InvalidValue* node, const Type* for_type) {
    VisitValue(node, for_type);
  }
  virtual void VisitNullValue(const NullValue* node, const Type* for_type) {
    VisitValue(node, for_type);
  }
  virtual void VisitRawValue(const RawValue* node, const Type* for_type) {
    VisitValue(node, for_type);
  }
  virtual void VisitBoolValue(const BoolValue* node, const Type* for_type) {
    VisitValue(node, for_type);
  }
  virtual void VisitIntegerValue(const IntegerValue* node, const Type* for_type) {
    VisitValue(node, for_type);
  }
  virtual void VisitDoubleValue(const DoubleValue* node, const Type* for_type) {
    VisitValue(node, for_type);
  }
  virtual void VisitStringValue(const StringValue* node, const Type* for_type) {
    VisitValue(node, for_type);
  }
  virtual void VisitHandleValue(const HandleValue* node, const Type* for_type) {
    VisitValue(node, for_type);
  }
  virtual void VisitUnionValue(const UnionValue* node, const Type* for_type) {
    node->value()->Visit(this, node->member().type());
  }
  virtual void VisitStructValue(const StructValue* node, const Type* for_type) {
    for (const auto& field : node->fields()) {
      field.second->Visit(this, field.first->type());
    }
  }
  virtual void VisitVectorValue(const VectorValue* node, const Type* for_type) {
    FX_DCHECK(for_type != nullptr);
    const Type* component_type = for_type->GetComponentType();
    FX_DCHECK(component_type != nullptr);
    for (const auto& value : node->values()) {
      value->Visit(this, component_type);
    }
  }
  virtual void VisitTableValue(const TableValue* node, const Type* for_type) {
    for (const auto& member : node->members()) {
      member.second->Visit(this, member.first->type());
    }
  }
  virtual void VisitFidlMessageValue(const FidlMessageValue* node, const Type* for_type) {
    if (node->decoded_request() != nullptr) {
      node->decoded_request()->Visit(this, nullptr);
    }
    if (node->decoded_response() != nullptr) {
      node->decoded_response()->Visit(this, nullptr);
    }
  }

  friend class Value;
  friend class InvalidValue;
  friend class NullValue;
  friend class RawValue;
  friend class BoolValue;
  friend class IntegerValue;
  friend class DoubleValue;
  friend class StringValue;
  friend class HandleValue;
  friend class UnionValue;
  friend class StructValue;
  friend class VectorValue;
  friend class TableValue;
  friend class FidlMessageValue;
};

}  // namespace fidl_codec

#endif  // SRC_LIB_FIDL_CODEC_VISITOR_H_
