tl json: support tl::TL_writer::Mode
GitOrigin-RevId: db6769e80f43f5fa2eedac5414cd2a44f8dcaf3c
This commit is contained in:
parent
d22a6751db
commit
620e4221f3
@ -10,5 +10,6 @@
|
||||
#include "td/tl/tl_generate.h"
|
||||
|
||||
int main() {
|
||||
td::gen_json_converter(td::tl::read_tl_config_from_file("scheme/td_api.tlo"), "td/telegram/td_api_json");
|
||||
td::gen_json_converter(td::tl::read_tl_config_from_file("scheme/td_api.tlo"), "td/telegram/td_api_json",
|
||||
td::tl::TL_writer::Server);
|
||||
}
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
namespace td {
|
||||
|
||||
using Mode = tl::TL_writer::Mode;
|
||||
|
||||
template <class T>
|
||||
void gen_to_json_constructor(StringBuilder &sb, const T *constructor, bool is_header) {
|
||||
sb << "void to_json(JsonValueScope &jv, "
|
||||
@ -55,8 +57,11 @@ void gen_to_json_constructor(StringBuilder &sb, const T *constructor, bool is_he
|
||||
sb << "}\n";
|
||||
}
|
||||
|
||||
void gen_to_json(StringBuilder &sb, const tl::simple::Schema &schema, bool is_header) {
|
||||
void gen_to_json(StringBuilder &sb, const tl::simple::Schema &schema, bool is_header, Mode mode) {
|
||||
for (auto *custom_type : schema.custom_types) {
|
||||
if (!((custom_type->is_query_ && mode != Mode::Server) || (custom_type->is_result_ && mode != Mode::Client))) {
|
||||
continue;
|
||||
}
|
||||
if (custom_type->constructors.size() > 1) {
|
||||
auto type_name = tl::simple::gen_cpp_name(custom_type->name);
|
||||
sb << "void to_json(JsonValueScope &jv, const td_api::" << type_name << " &object)";
|
||||
@ -74,6 +79,9 @@ void gen_to_json(StringBuilder &sb, const tl::simple::Schema &schema, bool is_he
|
||||
gen_to_json_constructor(sb, constructor, is_header);
|
||||
}
|
||||
}
|
||||
if (mode == Mode::Server) {
|
||||
return;
|
||||
}
|
||||
for (auto *function : schema.functions) {
|
||||
gen_to_json_constructor(sb, function, is_header);
|
||||
}
|
||||
@ -104,12 +112,18 @@ void gen_from_json_constructor(StringBuilder &sb, const T *constructor, bool is_
|
||||
}
|
||||
}
|
||||
|
||||
void gen_from_json(StringBuilder &sb, const tl::simple::Schema &schema, bool is_header) {
|
||||
void gen_from_json(StringBuilder &sb, const tl::simple::Schema &schema, bool is_header, Mode mode) {
|
||||
for (auto *custom_type : schema.custom_types) {
|
||||
if (!((custom_type->is_query_ && mode != Mode::Client) || (custom_type->is_result_ && mode != Mode::Server))) {
|
||||
continue;
|
||||
}
|
||||
for (auto *constructor : custom_type->constructors) {
|
||||
gen_from_json_constructor(sb, constructor, is_header);
|
||||
}
|
||||
}
|
||||
if (mode == Mode::Client) {
|
||||
return;
|
||||
}
|
||||
for (auto *function : schema.functions) {
|
||||
gen_from_json_constructor(sb, function, is_header);
|
||||
}
|
||||
@ -143,9 +157,12 @@ void gen_tl_constructor_from_string(StringBuilder &sb, Slice name, const Vec &ve
|
||||
sb << "}\n";
|
||||
}
|
||||
|
||||
void gen_tl_constructor_from_string(StringBuilder &sb, const tl::simple::Schema &schema, bool is_header) {
|
||||
void gen_tl_constructor_from_string(StringBuilder &sb, const tl::simple::Schema &schema, bool is_header, Mode mode) {
|
||||
Vec vec_for_nullary;
|
||||
for (auto *custom_type : schema.custom_types) {
|
||||
if (!((custom_type->is_query_ && mode != Mode::Client) || (custom_type->is_result_ && mode != Mode::Server))) {
|
||||
continue;
|
||||
}
|
||||
Vec vec;
|
||||
for (auto *constructor : custom_type->constructors) {
|
||||
vec.push_back(std::make_pair(constructor->id, constructor->name));
|
||||
@ -158,6 +175,9 @@ void gen_tl_constructor_from_string(StringBuilder &sb, const tl::simple::Schema
|
||||
}
|
||||
gen_tl_constructor_from_string(sb, "Object", vec_for_nullary, is_header);
|
||||
|
||||
if (mode == Mode::Client) {
|
||||
return;
|
||||
}
|
||||
Vec vec_for_function;
|
||||
for (auto *function : schema.functions) {
|
||||
vec_for_function.push_back(std::make_pair(function->id, function->name));
|
||||
@ -165,7 +185,8 @@ void gen_tl_constructor_from_string(StringBuilder &sb, const tl::simple::Schema
|
||||
gen_tl_constructor_from_string(sb, "Function", vec_for_function, is_header);
|
||||
}
|
||||
|
||||
void gen_json_converter_file(const tl::simple::Schema &schema, const std::string &file_name_base, bool is_header) {
|
||||
void gen_json_converter_file(const tl::simple::Schema &schema, const std::string &file_name_base, bool is_header,
|
||||
Mode mode) {
|
||||
auto file_name = is_header ? file_name_base + ".h" : file_name_base + ".cpp";
|
||||
file_name = "auto/" + file_name;
|
||||
auto old_file_content = [&] {
|
||||
@ -202,9 +223,9 @@ void gen_json_converter_file(const tl::simple::Schema &schema, const std::string
|
||||
}
|
||||
sb << "namespace td {\n";
|
||||
sb << "namespace td_api{\n";
|
||||
gen_tl_constructor_from_string(sb, schema, is_header);
|
||||
gen_from_json(sb, schema, is_header);
|
||||
gen_to_json(sb, schema, is_header);
|
||||
gen_tl_constructor_from_string(sb, schema, is_header, mode);
|
||||
gen_from_json(sb, schema, is_header, mode);
|
||||
gen_to_json(sb, schema, is_header, mode);
|
||||
sb << "} // namespace td_api\n";
|
||||
sb << "} // namespace td\n";
|
||||
|
||||
@ -226,10 +247,10 @@ void gen_json_converter_file(const tl::simple::Schema &schema, const std::string
|
||||
}
|
||||
}
|
||||
|
||||
void gen_json_converter(const tl::tl_config &config, const std::string &file_name) {
|
||||
void gen_json_converter(const tl::tl_config &config, const std::string &file_name, Mode mode) {
|
||||
tl::simple::Schema schema(config);
|
||||
gen_json_converter_file(schema, file_name, true);
|
||||
gen_json_converter_file(schema, file_name, false);
|
||||
gen_json_converter_file(schema, file_name, true, mode);
|
||||
gen_json_converter_file(schema, file_name, false, mode);
|
||||
}
|
||||
|
||||
} // namespace td
|
||||
|
@ -7,11 +7,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "td/tl/tl_config.h"
|
||||
#include "td/tl/tl_writer.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace td {
|
||||
|
||||
void gen_json_converter(const tl::tl_config &config, const std::string &file_name);
|
||||
void gen_json_converter(const tl::tl_config &config, const std::string &file_name, tl::TL_writer::Mode mode);
|
||||
|
||||
} // namespace td
|
||||
|
@ -589,13 +589,13 @@ class CliClient final : public Actor {
|
||||
|
||||
auto as_json_str = json_encode<std::string>(ToJson(result));
|
||||
// LOG(INFO) << "Receive result [" << generation << "][id=" << id << "] " << as_json_str;
|
||||
auto copy_as_json_str = as_json_str;
|
||||
auto as_json_value = json_decode(copy_as_json_str).move_as_ok();
|
||||
td_api::object_ptr<td_api::Object> object;
|
||||
from_json(object, as_json_value).ensure();
|
||||
CHECK(object != nullptr);
|
||||
auto as_json_str2 = json_encode<std::string>(ToJson(object));
|
||||
LOG_CHECK(as_json_str == as_json_str2) << "\n" << tag("a", as_json_str) << "\n" << tag("b", as_json_str2);
|
||||
//auto copy_as_json_str = as_json_str;
|
||||
//auto as_json_value = json_decode(copy_as_json_str).move_as_ok();
|
||||
//td_api::object_ptr<td_api::Object> object;
|
||||
//from_json(object, as_json_value).ensure();
|
||||
//CHECK(object != nullptr);
|
||||
//auto as_json_str2 = json_encode<std::string>(ToJson(object));
|
||||
//LOG_CHECK(as_json_str == as_json_str2) << "\n" << tag("a", as_json_str) << "\n" << tag("b", as_json_str2);
|
||||
// LOG(INFO) << "Receive result [" << generation << "][id=" << id << "] " << as_json_str;
|
||||
|
||||
if (generation != generation_) {
|
||||
|
@ -39,11 +39,22 @@ inline void to_json(JsonValueScope &jv, const JsonVectorInt64 &vec) {
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auto lazy_to_json(JsonValueScope &jv, const T &t) -> decltype(td_api::to_json(jv, t)) {
|
||||
return td_api::to_json(jv, t);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void lazy_to_json(std::reference_wrapper<JsonValueScope>, const T &t) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
inline void to_json(JsonValueScope &jv, const td_api::Object &object) {
|
||||
td_api::downcast_call(const_cast<td_api::Object &>(object), [&jv](const auto &object) { to_json(jv, object); });
|
||||
td_api::downcast_call(const_cast<td_api::Object &>(object), [&jv](const auto &object) { lazy_to_json(jv, object); });
|
||||
}
|
||||
inline void to_json(JsonValueScope &jv, const td_api::Function &object) {
|
||||
td_api::downcast_call(const_cast<td_api::Function &>(object), [&jv](const auto &object) { to_json(jv, object); });
|
||||
td_api::downcast_call(const_cast<td_api::Function &>(object),
|
||||
[&jv](const auto &object) { lazy_to_json(jv, object); });
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
@ -16,6 +16,8 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace td {
|
||||
namespace tl {
|
||||
namespace simple {
|
||||
@ -63,6 +65,9 @@ struct Constructor {
|
||||
struct CustomType {
|
||||
std::string name;
|
||||
std::vector<const Constructor *> constructors;
|
||||
|
||||
mutable bool is_result_{false};
|
||||
mutable bool is_query_{false};
|
||||
};
|
||||
|
||||
struct Function {
|
||||
@ -91,6 +96,23 @@ class Schema {
|
||||
auto *from_function = config.get_function_by_num(function_num);
|
||||
functions.push_back(get_function(from_function));
|
||||
}
|
||||
for (auto &function : functions_) {
|
||||
mark_result(function->type);
|
||||
for (auto &arg : function->args) {
|
||||
mark_query(arg.type);
|
||||
}
|
||||
}
|
||||
|
||||
//for (auto custom_type : custom_types) {
|
||||
//std::cerr << custom_type->name;
|
||||
//if (custom_type->is_result_) {
|
||||
//std::cerr << " result";
|
||||
//}
|
||||
//if (custom_type->is_query_) {
|
||||
//std::cerr << " query";
|
||||
//}
|
||||
//std::cerr << std::endl;
|
||||
//}
|
||||
}
|
||||
|
||||
std::vector<const CustomType *> custom_types;
|
||||
@ -107,6 +129,32 @@ class Schema {
|
||||
std::map<std::int32_t, Constructor *> constructor_by_id;
|
||||
std::map<std::int32_t, Function *> function_by_id;
|
||||
|
||||
void mark_result(const Type *type) {
|
||||
do_mark(type, true);
|
||||
}
|
||||
void mark_query(const Type *type) {
|
||||
do_mark(type, false);
|
||||
}
|
||||
void do_mark(const Type *type, bool is_result) {
|
||||
if (type->type == Type::Vector) {
|
||||
return do_mark(type->vector_value_type, is_result);
|
||||
}
|
||||
if (type->type != Type::Custom) {
|
||||
return;
|
||||
}
|
||||
auto *custom = type->custom;
|
||||
auto &was = is_result ? custom->is_result_ : custom->is_query_;
|
||||
if (was) {
|
||||
return;
|
||||
}
|
||||
was = true;
|
||||
for (auto constructor : custom->constructors) {
|
||||
for (auto &arg : constructor->args) {
|
||||
do_mark(arg.type, is_result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const Type *get_type(const tl_type *from_type) {
|
||||
auto &type = type_by_id[from_type->id];
|
||||
if (!type) {
|
||||
|
Reference in New Issue
Block a user