aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorArseny Smirnov <arseny30@gmail.com>2019-07-01 10:43:31 +0200
committerArseny Smirnov <arseny30@gmail.com>2019-07-01 10:43:31 +0200
commit620e4221f3b748d341fb3deff6241518bf3d8440 (patch)
treeb31de5091afc98dc2db3975dd41fb1523b0b2cb9
parentd22a6751dbdbdc357f1a473dc6a93559964baaad (diff)
tl json: support tl::TL_writer::Mode
GitOrigin-RevId: db6769e80f43f5fa2eedac5414cd2a44f8dcaf3c
-rw-r--r--td/generate/generate_json.cpp3
-rw-r--r--td/generate/tl_json_converter.cpp41
-rw-r--r--td/generate/tl_json_converter.h3
-rw-r--r--td/telegram/cli.cpp14
-rw-r--r--td/tl/tl_json.h15
-rw-r--r--tdtl/td/tl/tl_simple.h48
6 files changed, 103 insertions, 21 deletions
diff --git a/td/generate/generate_json.cpp b/td/generate/generate_json.cpp
index 5b75a88e3..d8d64eebb 100644
--- a/td/generate/generate_json.cpp
+++ b/td/generate/generate_json.cpp
@@ -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);
}
diff --git a/td/generate/tl_json_converter.cpp b/td/generate/tl_json_converter.cpp
index 42cd68772..5910ade47 100644
--- a/td/generate/tl_json_converter.cpp
+++ b/td/generate/tl_json_converter.cpp
@@ -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
diff --git a/td/generate/tl_json_converter.h b/td/generate/tl_json_converter.h
index d37de7ff4..ded58af47 100644
--- a/td/generate/tl_json_converter.h
+++ b/td/generate/tl_json_converter.h
@@ -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
diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp
index f7cf2aa31..ec22f5728 100644
--- a/td/telegram/cli.cpp
+++ b/td/telegram/cli.cpp
@@ -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_) {
diff --git a/td/tl/tl_json.h b/td/tl/tl_json.h
index 6eecde75c..a740f18bf 100644
--- a/td/tl/tl_json.h
+++ b/td/tl/tl_json.h
@@ -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>
diff --git a/tdtl/td/tl/tl_simple.h b/tdtl/td/tl/tl_simple.h
index 2b51fda97..ea53a0620 100644
--- a/tdtl/td/tl/tl_simple.h
+++ b/tdtl/td/tl/tl_simple.h
@@ -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) {