blob: 7538e469d6902451d7deb493d51b8ed3577b9cef [file] [log] [blame]
/*
* Copyright 2020 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 TOOLS_FIDLCAT_LIB_CODE_GENERATOR_CODE_GENERATOR_H_
#define TOOLS_FIDLCAT_LIB_CODE_GENERATOR_CODE_GENERATOR_H_
#include <ctime>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <map>
#include <memory>
#include "src/lib/fidl_codec/library_loader.h"
#include "src/lib/fidl_codec/printer.h"
#include "src/lib/fidl_codec/wire_object.h"
#include "tools/fidlcat/lib/event.h"
#include "tools/fidlcat/lib/syscall_decoder_dispatcher.h"
namespace fidlcat {
std::string FidlMethodToIncludePath(std::string_view identifier);
std::string ToSnakeCase(std::string_view str);
class FidlCallInfo {
public:
FidlCallInfo(bool crashed, std::string_view enclosing_interface_name, zx_handle_t handle_id,
zx_txid_t txid, SyscallKind kind, std::string_view method_name,
const fidl_codec::Struct* struct_input, const fidl_codec::Struct* struct_output,
const fidl_codec::StructValue* decoded_input_value,
const fidl_codec::StructValue* decoded_output_value)
: crashed_(crashed),
enclosing_interface_name_(enclosing_interface_name),
handle_id_(handle_id),
txid_(txid),
kind_(kind),
method_name_(method_name),
struct_input_(struct_input),
struct_output_(struct_output),
decoded_input_value_(decoded_input_value),
decoded_output_value_(decoded_output_value) {}
bool crashed() const { return crashed_; }
zx_handle_t handle_id() const { return handle_id_; }
zx_txid_t txid() const { return txid_; }
SyscallKind kind() const { return kind_; }
const std::string& method_name() const { return method_name_; }
const std::string& enclosing_interface_name() const { return enclosing_interface_name_; }
const fidl_codec::Struct* struct_input() const { return struct_input_; }
const fidl_codec::Struct* struct_output() const { return struct_output_; }
const fidl_codec::StructValue* decoded_input_value() const { return decoded_input_value_; }
const fidl_codec::StructValue* decoded_output_value() const { return decoded_output_value_; }
size_t sequence_number() const { return sequence_number_; }
void SetSequenceNumber(size_t sequence_number) { sequence_number_ = sequence_number; }
private:
// True if server crashes in response to a zx_channel_call
const bool crashed_ = false;
// Interface name for the FIDL call (e.g. fidl.examples.echo/Echo)
const std::string enclosing_interface_name_;
// Handle id of the FIDL call, used to reconcile writes and reads
const zx_handle_t handle_id_;
// Transaction id of the syscall, used to reconcile writes and reads
const zx_txid_t txid_;
// The system call used as part of the FIDL call
const SyscallKind kind_;
// FIDL method name (e.g. EchoString)
const std::string method_name_;
// Input struct definition
const fidl_codec::Struct* const struct_input_;
// Output struct definition
const fidl_codec::Struct* const struct_output_;
// Decoded input value
const fidl_codec::StructValue* const decoded_input_value_;
// Decoded output value
const fidl_codec::StructValue* const decoded_output_value_;
// Sequence number in the channel
size_t sequence_number_;
};
std::unique_ptr<FidlCallInfo> OutputEventToFidlCallInfo(OutputEvent* output_event);
class CodeGenerator {
public:
CodeGenerator() {}
const std::map<zx_handle_t, std::vector<std::unique_ptr<FidlCallInfo>>>& call_log() {
return call_log_;
}
void AddEventToLog(std::unique_ptr<FidlCallInfo> call_info) {
call_log_[call_info->handle_id()].emplace_back(std::move(call_info));
}
void AddFidlHeaderForInterface(std::string_view enclosing_interface_name) {
fidl_headers_.insert(FidlMethodToIncludePath(enclosing_interface_name));
}
std::string AcquireUniqueName(const std::string& prefix) {
return prefix + "_" + std::to_string(unique_name_counter_[prefix]++);
}
void GenerateIncludes(fidl_codec::PrettyPrinter& printer);
void GenerateFidlIncludes(fidl_codec::PrettyPrinter& printer);
private:
// A log of processed events.
std::map<zx_handle_t, std::vector<std::unique_ptr<FidlCallInfo>>> call_log_;
// Paths for FIDL-related #include directives.
std::set<std::string> fidl_headers_;
// Counter for unique variable ids.
std::map<std::string, int> unique_name_counter_;
};
} // namespace fidlcat
#endif // TOOLS_FIDLCAT_LIB_CODE_GENERATOR_CODE_GENERATOR_H_