// 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.

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

#include <lib/syslog/cpp/macros.h>

#include <iostream>
#include <memory>
#include <sstream>
#include <vector>

#include <rapidjson/stringbuffer.h>
#include <rapidjson/writer.h>

#include "src/lib/fidl_codec/json_visitor.h"
#include "src/lib/fidl_codec/library_loader.h"
#include "src/lib/fidl_codec/printer.h"
#include "src/lib/fidl_codec/status.h"
#include "src/lib/fidl_codec/visitor.h"
#include "src/lib/fidl_codec/wire_types.h"

namespace fidl_codec {

void Value::ExtractJson(rapidjson::Document::AllocatorType& allocator,
                        rapidjson::Value& result) const {
  JsonVisitor visitor(&result, &allocator);
  Visit(&visitor, nullptr);
}

std::string DocumentToString(rapidjson::Document* document) {
  rapidjson::StringBuffer output;
  rapidjson::Writer<rapidjson::StringBuffer> writer(output);
  document->Accept(writer);
  return output.GetString();
}

void InvalidValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitInvalidValue(this, for_type);
}

void EmptyPayloadValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitEmptyPayloadValue(this, for_type);
}

void NullValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitNullValue(this, for_type);
}

size_t RawValue::DisplaySize(const Type* /*for_type*/, size_t /*remaining_size*/) const {
  return data_.empty() ? 0 : data_.size() * 3 - 1;
}

void RawValue::PrettyPrint(const Type* for_type, PrettyPrinter& printer) const {
  if (data_.empty()) {
    return;
  }
  size_t buffer_size = data_.size() * 3;
  std::vector<char> buffer(buffer_size);
  for (size_t i = 0; i < data_.size(); ++i) {
    if (i != 0) {
      buffer[i * 3 - 1] = ' ';
    }
    snprintf(buffer.data() + (i * 3), 4, "%02x", data_[i]);
  }
  printer << buffer.data();
}

void RawValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitRawValue(this, for_type);
}

size_t BoolValue::DisplaySize(const Type* /*for_type*/, size_t /*remaining_size*/) const {
  constexpr int kTrueSize = 4;
  constexpr int kFalseSize = 5;
  return value_ ? kTrueSize : kFalseSize;
}

void BoolValue::PrettyPrint(const Type* for_type, PrettyPrinter& printer) const {
  printer << Blue << (value_ ? "true" : "false") << ResetColor;
}

void BoolValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitBoolValue(this, for_type);
}

uint8_t IntegerValue::GetUint8Value() const {
  return (!negative_ && (absolute_value_ < 0x100)) ? static_cast<uint8_t>(absolute_value_) : 0;
}

size_t IntegerValue::DisplaySize(const Type* for_type, size_t /*remaining_size*/) const {
  std::stringstream dummyStream;
  auto dummyPrinter = PrettyPrinter(dummyStream, WithoutColors, true, "", INT_MAX, false);
  for_type->PrettyPrint(this, dummyPrinter);
  return dummyStream.str().length();
}

void IntegerValue::PrettyPrint(const Type* for_type, PrettyPrinter& printer) const {
  FX_DCHECK(for_type != nullptr);
  for_type->PrettyPrint(this, printer);
}

void IntegerValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitIntegerValue(this, for_type);
}

size_t ActualAndRequestedValue::DisplaySize(const Type* for_type, size_t /*remaining_size*/) const {
  std::stringstream dummyStream;
  auto dummyPrinter = PrettyPrinter(dummyStream, WithoutColors, true, "", INT_MAX, false);
  for_type->PrettyPrint(this, dummyPrinter);
  return dummyStream.str().length();
}

void ActualAndRequestedValue::PrettyPrint(const Type* for_type, PrettyPrinter& printer) const {
  FX_DCHECK(for_type != nullptr);
  for_type->PrettyPrint(this, printer);
}

void ActualAndRequestedValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitActualAndRequestedValue(this, for_type);
}

size_t DoubleValue::DisplaySize(const Type* for_type, size_t /*remaining_size*/) const {
  return std::to_string(value_).size();
}

void DoubleValue::PrettyPrint(const Type* for_type, PrettyPrinter& printer) const {
  FX_DCHECK(for_type != nullptr);
  for_type->PrettyPrint(this, printer);
}

void DoubleValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitDoubleValue(this, for_type);
}

size_t StringValue::DisplaySize(const Type* /*for_type*/, size_t /*remaining_size*/) const {
  return string_.size() + 2;  // The two quotes.
}

void StringValue::PrettyPrint(const Type* for_type, PrettyPrinter& printer) const {
  printer.DisplayString(string_);
}

void StringValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitStringValue(this, for_type);
}

bool HandleValue::NeedsToLoadHandleInfo(int64_t timestamp, zx_koid_t tid,
                                        semantic::HandleSemantic* handle_semantic) const {
  if (handle_.handle == ZX_HANDLE_INVALID) {
    return false;
  }
  return handle_semantic->NeedsToLoadHandleInfo(timestamp, tid, handle_.handle);
}

size_t HandleValue::DisplaySize(const Type* /*for_type*/, size_t /*remaining_size*/) const {
  return std::to_string(handle_.handle).size();
}

void HandleValue::PrettyPrint(const Type* /*for_type*/, PrettyPrinter& printer) const {
  printer.DisplayHandle(handle_);
}

void HandleValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitHandleValue(this, for_type);
}

bool UnionValue::NeedsToLoadHandleInfo(int64_t timestamp, zx_koid_t tid,
                                       semantic::HandleSemantic* handle_semantic) const {
  return value_->NeedsToLoadHandleInfo(timestamp, tid, handle_semantic);
}

size_t UnionValue::DisplaySize(const Type* for_type, size_t remaining_size) const {
  // Two characters for the opening brace ("{ ") + three characters for equal
  // (" = ") and two characters for the closing brace (" }").
  constexpr int kExtraSize = 7;
  size_t size = member_.name().size() + kExtraSize;
  // Two characters for ": ".
  size += member_.type()->Name().size() + 2;
  size += value_->DisplaySize(member_.type(), remaining_size - size);
  return size;
}

void UnionValue::PrettyPrint(const Type* for_type, PrettyPrinter& printer) const {
  if (DisplaySize(for_type, printer.remaining_size()) <= printer.remaining_size()) {
    printer << "{ " << member_.name() << ": ";
    member_.type()->PrettyPrint(printer);
    printer << " = ";
    value_->PrettyPrint(member_.type(), printer);
    printer << " }";
  } else {
    printer << "{\n";
    {
      Indent indent(printer);
      printer << member_.name() << ": ";
      member_.type()->PrettyPrint(printer);
      printer << " = ";
      value_->PrettyPrint(member_.type(), printer);
      printer << '\n';
    }
    printer << "}";
  }
}

void UnionValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitUnionValue(this, for_type);
}

std::pair<const Type*, const Value*> StructValue::GetFieldValue(std::string_view field_name) const {
  for (const auto& field : fields_) {
    if (field.first->name() == field_name) {
      return std::make_pair(field.first->type(), field.second.get());
    }
  }
  return std::make_pair(nullptr, nullptr);
}

void StructValue::AddField(std::string_view name, uint32_t id, std::unique_ptr<Value> value) {
  StructMember* member = struct_definition_.SearchMember(name, id);
  if (member != nullptr) {
    AddField(member, std::move(value));
  }
}

bool StructValue::NeedsToLoadHandleInfo(int64_t timestamp, zx_koid_t tid,
                                        semantic::HandleSemantic* handle_semantic) const {
  for (const auto& field : fields_) {
    if (field.second->NeedsToLoadHandleInfo(timestamp, tid, handle_semantic)) {
      return true;
    }
  }
  return false;
}

size_t StructValue::DisplaySize(const Type* for_type, size_t remaining_size) const {
  size_t size = 0;
  for (const auto& member : struct_definition_.members()) {
    auto it = fields_.find(member.get());
    if (it == fields_.end())
      continue;
    // Two characters for the separator ("{ " or ", ") and three characters for
    // equal (" = ").
    constexpr int kExtraSize = 5;
    size += member->name().size() + kExtraSize;
    // Two characters for ": ".
    size += member->type()->Name().size() + 2;
    size += it->second->DisplaySize(member->type(), remaining_size - size);
    if (size > remaining_size) {
      return size;
    }
  }
  // Two characters for the closing brace (" }").
  size += 2;
  return size;
}

void StructValue::PrettyPrint(const Type* for_type, PrettyPrinter& printer) const {
  if (fields_.empty()) {
    printer << "{}";
  } else if (DisplaySize(for_type, printer.remaining_size()) <= printer.remaining_size()) {
    const char* separator = "{ ";
    for (const auto& member : struct_definition_.members()) {
      auto it = fields_.find(member.get());
      if (it == fields_.end())
        continue;
      printer << separator << member->name() << ": ";
      member->type()->PrettyPrint(printer);
      printer << " = ";
      it->second->PrettyPrint(member->type(), printer);
      separator = ", ";
    }
    printer << " }";
  } else {
    printer << "{\n";
    {
      Indent indent(printer);
      for (const auto& member : struct_definition_.members()) {
        auto it = fields_.find(member.get());
        if (it == fields_.end())
          continue;
        std::string type_name = member->type()->Name();
        printer << member->name() << ": ";
        member->type()->PrettyPrint(printer);
        printer << " = ";
        it->second->PrettyPrint(member->type(), printer);
        printer << "\n";
      }
    }
    printer << '}';
  }
}

void StructValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitStructValue(this, for_type);
}

bool VectorValue::NeedsToLoadHandleInfo(int64_t timestamp, zx_koid_t tid,
                                        semantic::HandleSemantic* handle_semantic) const {
  for (const auto& value : values_) {
    if (value->NeedsToLoadHandleInfo(timestamp, tid, handle_semantic)) {
      return true;
    }
  }
  return false;
}

size_t VectorValue::DisplaySize(const Type* for_type, size_t remaining_size) const {
  FX_DCHECK(for_type != nullptr);
  if (values_.empty()) {
    return 2;  // The two brackets.
  }
  if (is_string_) {
    return values_.size() + 2;  // The string and the two quotes.
  }
  const Type* component_type = for_type->GetComponentType();
  FX_DCHECK(component_type != nullptr);
  size_t size = 0;
  for (const auto& value : values_) {
    // Two characters for the separator ("[ " or ", ").
    size += value->DisplaySize(component_type, remaining_size - size) + 2;
    if (size > remaining_size) {
      return size;
    }
  }
  // Two characters for the closing bracket (" ]").
  size += 2;
  return size;
}

void VectorValue::PrettyPrint(const Type* for_type, PrettyPrinter& printer) const {
  FX_DCHECK(for_type != nullptr);
  if (values_.empty()) {
    printer << "[]";
  } else if (is_string_) {
    if (has_new_line_) {
      printer << "[\n";
      {
        Indent indent(printer);
        printer << Red;
        for (const auto& value : values_) {
          printer << static_cast<char>(value->GetUint8Value());
        }
        printer << ResetColor;
      }
      printer << '\n';
      printer << ']';
    } else {
      printer << Red << '"';
      for (const auto& value : values_) {
        printer << static_cast<char>(value->GetUint8Value());
      }
      printer << '"' << ResetColor;
    }
  } else if (DisplaySize(for_type, printer.remaining_size()) <= printer.remaining_size()) {
    const Type* component_type = for_type->GetComponentType();
    FX_DCHECK(component_type != nullptr);
    const char* separator = "[ ";
    for (const auto& value : values_) {
      printer << separator;
      separator = ", ";
      value->PrettyPrint(component_type, printer);
    }
    printer << " ]";
  } else {
    const Type* component_type = for_type->GetComponentType();
    FX_DCHECK(component_type != nullptr);
    printer << "[\n";
    {
      Indent indent(printer);
      for (const auto& value : values_) {
        size_t value_size = value->DisplaySize(component_type, printer.remaining_size());
        if (!printer.LineEmpty()) {
          if (value_size + 3 > printer.remaining_size()) {
            printer << "\n";
          } else {
            printer << ", ";
          }
        }
        value->PrettyPrint(component_type, printer);
      }
      printer << '\n';
    }
    printer << ']';
  }
}

void VectorValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitVectorValue(this, for_type);
}

bool TableValue::AddMember(std::string_view name, std::unique_ptr<Value> value) {
  const TableMember* member = table_definition_.SearchMember(name);
  if (member == nullptr) {
    return false;
  }
  AddMember(member, std::move(value));
  return true;
}

bool TableValue::NeedsToLoadHandleInfo(int64_t timestamp, zx_koid_t tid,
                                       semantic::HandleSemantic* handle_semantic) const {
  for (const auto& member : members_) {
    if (member.second->NeedsToLoadHandleInfo(timestamp, tid, handle_semantic)) {
      return true;
    }
  }
  return false;
}

size_t TableValue::DisplaySize(const Type* for_type, size_t remaining_size) const {
  size_t size = 0;
  for (const auto& member : table_definition_.members()) {
    if (member != nullptr) {
      auto it = members_.find(member.get());
      if ((it == members_.end()) || (it->second == nullptr) || it->second->IsNull())
        continue;
      // Two characters for the separator ("{ " or ", "), three characters for " = ".
      size += member->name().size() + 2 + 3;
      // Two characters for ": ".
      size += member->type()->Name().size() + 2;
      size += it->second->DisplaySize(member->type(), remaining_size - size);
      if (size > remaining_size) {
        return size;
      }
    }
  }
  // Two characters for the closing brace (" }").
  size += 2;
  return size;
}

void TableValue::PrettyPrint(const Type* for_type, PrettyPrinter& printer) const {
  size_t display_size = DisplaySize(for_type, printer.remaining_size());
  if (display_size == 2) {
    printer << "{}";
  } else if (display_size <= printer.remaining_size()) {
    const char* separator = "{ ";
    for (const auto& member : table_definition_.members()) {
      if (member != nullptr) {
        auto it = members_.find(member.get());
        if ((it == members_.end()) || (it->second == nullptr) || it->second->IsNull())
          continue;
        printer << separator << member->name() << ": " << Green << member->type()->Name()
                << ResetColor << " = ";
        separator = ", ";
        it->second->PrettyPrint(member->type(), printer);
      }
    }
    printer << " }";
  } else {
    printer << "{\n";
    {
      Indent indent(printer);
      for (const auto& member : table_definition_.members()) {
        if (member != nullptr) {
          auto it = members_.find(member.get());
          if ((it == members_.end()) || (it->second == nullptr) || it->second->IsNull())
            continue;
          std::string type_name = member->type()->Name();
          printer << member->name() << ": " << Green << type_name << ResetColor << " = ";
          it->second->PrettyPrint(member->type(), printer);
          printer << "\n";
        }
      }
    }
    printer << '}';
  }
}

void TableValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitTableValue(this, for_type);
}

FidlMessageValue::FidlMessageValue(fidl_codec::DecodedMessage* message, std::string global_errors,
                                   const uint8_t* bytes, uint32_t num_bytes,
                                   const zx_handle_disposition_t* handles, uint32_t num_handles)
    : txid_(message->txid()),
      ordinal_(message->ordinal()),
      global_errors_(std::move(global_errors)),
      epitaph_error_(
          (message->ordinal() == kFidlOrdinalEpitaph) ? StatusName(message->epitaph_error()) : ""),
      received_(message->received()),
      is_request_(message->is_request()),
      unknown_direction_(message->direction() == Direction::kUnknown),
      method_(message->method()),
      bytes_(bytes, bytes + num_bytes),
      handles_(handles, handles + num_handles),
      decoded_request_((unknown_direction_ || is_request_) ? std::move(message->decoded_request())
                                                           : nullptr),
      request_errors_((unknown_direction_ || is_request_) ? message->request_error_stream().str()
                                                          : ""),
      decoded_response_(
          (unknown_direction_ || !is_request_) ? std::move(message->decoded_response()) : nullptr),
      response_errors_((unknown_direction_ || !is_request_) ? message->response_error_stream().str()
                                                            : "") {}

bool FidlMessageValue::NeedsToLoadHandleInfo(int64_t timestamp, zx_koid_t tid,
                                             semantic::HandleSemantic* handle_semantic) const {
  for (const auto& handle : handles_) {
    auto inferred_handle_info = handle_semantic->GetInferredHandleInfo(tid, handle.handle);
    if (inferred_handle_info == nullptr) {
      return true;
    }
  }
  return false;
}

size_t FidlMessageValue::DisplaySize(const Type* for_type, size_t remaining_size) const {
  return 0;
}

void FidlMessageValue::PrettyPrint(const Type* for_type, PrettyPrinter& printer) const {
  PrintMessage(printer);
  DumpMessage(printer);
}

void FidlMessageValue::PrintMessage(PrettyPrinter& printer) const {
  if (!global_errors_.empty()) {
    printer << global_errors_;
    return;
  }
  if (ordinal_ == kFidlOrdinalEpitaph) {
    printer << fidl_codec::WhiteOnMagenta << (received_ ? "received" : "sent") << " epitaph"
            << fidl_codec::ResetColor << ' ' << fidl_codec::Red << epitaph_error_
            << fidl_codec::ResetColor << "\n";
    return;
  }

  if (unknown_direction_) {
    bool matched_request = (decoded_request_ != nullptr) && request_errors_.empty();
    bool matched_response = (decoded_response_ != nullptr) && response_errors_.empty();
    if (matched_request || matched_response) {
      printer << fidl_codec::Red << "Can't determine request/response." << fidl_codec::ResetColor
              << " it can be:\n";
      fidl_codec::Indent indent(printer);
      PrintMessageBody(printer);
      return;
    }
  }
  PrintMessageBody(printer);
}

void FidlMessageValue::PrintMessageBody(PrettyPrinter& printer) const {
  if (matched_request() && (is_request_ || unknown_direction_)) {
    printer << fidl_codec::WhiteOnMagenta << (received_ ? "received" : "sent") << " request"
            << fidl_codec::ResetColor << ' ' << fidl_codec::Green
            << method_->enclosing_protocol().name() << '.' << method_->name()
            << fidl_codec::ResetColor << " = ";
    if (printer.pretty_print()) {
      decoded_request_->PrettyPrint(nullptr, printer);
      printer << '\n';
    } else {
      rapidjson::Document actual_request;
      if (decoded_request_ != nullptr) {
        decoded_request_->ExtractJson(actual_request.GetAllocator(), actual_request);
      }
      printer << DocumentToString(&actual_request) << '\n';
    }
  }
  if (matched_response() && (!is_request_ || unknown_direction_)) {
    printer << fidl_codec::WhiteOnMagenta << (received_ ? "received" : "sent")
            << (method_->has_request() ? " response" : " event") << fidl_codec::ResetColor << ' '
            << fidl_codec::Green << method_->enclosing_protocol().name() << '.' << method_->name()
            << fidl_codec::ResetColor << " = ";
    if (printer.pretty_print()) {
      decoded_response_->PrettyPrint(nullptr, printer);
      printer << '\n';
    } else {
      rapidjson::Document actual_response;
      if (decoded_response_ != nullptr) {
        decoded_response_->ExtractJson(actual_response.GetAllocator(), actual_response);
      }
      printer << DocumentToString(&actual_response) << '\n';
    }
  }
  if (matched_request() || matched_response()) {
    return;
  }
  if (!request_errors_.empty()) {
    printer << fidl_codec::Red << (received_ ? "received" : "sent") << " request errors"
            << fidl_codec::ResetColor << ":\n";
    {
      Indent indent(printer);
      printer << request_errors_;
    }
    if (decoded_request_ != nullptr) {
      printer << fidl_codec::WhiteOnMagenta << (received_ ? "received" : "sent") << " request"
              << fidl_codec::ResetColor << ' ' << fidl_codec::Green
              << method_->enclosing_protocol().name() << '.' << method_->name()
              << fidl_codec::ResetColor << " = ";
      decoded_request_->PrettyPrint(nullptr, printer);
      printer << '\n';
    }
  }
  if (!response_errors_.empty()) {
    printer << fidl_codec::Red << (received_ ? "received" : "sent")
            << (method_->has_request() ? " response errors" : " event errors")
            << fidl_codec::ResetColor << ":\n";
    {
      Indent indent(printer);
      printer << response_errors_;
    }
    if (decoded_response_ != nullptr) {
      printer << fidl_codec::WhiteOnMagenta << (received_ ? "received" : "sent")
              << (method_->has_request() ? " response" : " event") << fidl_codec::ResetColor << ' '
              << fidl_codec::Green << method_->enclosing_protocol().name() << '.' << method_->name()
              << fidl_codec::ResetColor << " = ";
      decoded_response_->PrettyPrint(nullptr, printer);
      printer << '\n';
    }
  }
}

void FidlMessageValue::DumpMessage(PrettyPrinter& printer) const {
  constexpr int kPatternColorSize = 4;
  constexpr int kPatternSize = 8;
  constexpr int kLineSize = 16;
  constexpr int kLineHandleSize = 4;
  constexpr int kCharactersPerByte = 2;
  if ((decoded_request_ == nullptr) && (decoded_response_ == nullptr) &&
      (ordinal_ != kFidlOrdinalEpitaph)) {
    printer << fidl_codec::Red << "Can't decode message: ";
  } else if (printer.DumpMessages()) {
    printer << "Message: ";
  } else {
    return;
  }
  printer << "num_bytes=" << bytes_.size() << " num_handles=" << handles_.size();
  if (txid_ != 0) {
    printer << " txid=" << std::hex << txid_ << std::dec;
  }
  if (ordinal_ != 0) {
    printer << " ordinal=" << std::hex << ordinal_ << std::dec;
    if (method_ != nullptr) {
      printer << '(' << method_->enclosing_protocol().name() << '.' << method_->name() << ')';
    }
  }
  printer << fidl_codec::ResetColor << '\n';
  {
    Indent indent_data(printer);
    printer << "data=";
    const char* separator = "";
    Indent indent_dump(printer);
    for (uint32_t i = 0; i < bytes_.size(); ++i) {
      // Display 16 bytes per line.
      if (i % kLineSize == 0) {
        std::vector<char> buffer(sizeof(uint32_t) * kCharactersPerByte + 1);
        snprintf(buffer.data(), buffer.size(), "%04x", i);
        printer << separator << "\n";
        printer << buffer.data() << ": ";
        separator = "";
      }
      // Display 4 bytes in red then four bytes in black ...
      if (i % kPatternSize == 0) {
        printer << fidl_codec::Red;
      } else if (i % kPatternColorSize == 0) {
        printer << fidl_codec::ResetColor;
      }
      std::vector<char> buffer(sizeof(uint8_t) * kCharactersPerByte + 1);
      snprintf(buffer.data(), buffer.size(), "%02x", bytes_[i]);
      printer << separator << buffer.data();
      separator = ", ";
    }
    printer << fidl_codec::ResetColor << '\n';
  }
  if (handles_.size() > 0) {
    Indent indent_data(printer);
    printer << "handles=";
    Indent indent_dump(printer);
    const char* separator = "";
    for (uint32_t i = 0; i < handles_.size(); ++i) {
      // Display 4 bytes per line.
      if (i % kLineHandleSize == 0) {
        std::vector<char> buffer(sizeof(uint32_t) * kCharactersPerByte + 1);
        snprintf(buffer.data(), buffer.size(), "%04x", i);
        printer << separator << "\n";
        printer << buffer.data() << ": ";
        separator = "";
      }
      std::vector<char> buffer(sizeof(zx_handle_t) * kCharactersPerByte + 1);
      snprintf(buffer.data(), buffer.size(), "%08x", handles_[i].handle);
      printer << separator << buffer.data();
      separator = ", ";
    }
    printer << '\n';
  }
}

void FidlMessageValue::Visit(Visitor* visitor, const Type* for_type) const {
  visitor->VisitFidlMessageValue(this, for_type);
}

}  // namespace fidl_codec
