--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/dart_cion_gen_base.h"
+#include "idlc/gen_cion/dart_cion_gen_base_cb.h"
+
+#include <algorithm>
+#include <ctime>
+#include <sstream>
+#include <stack>
+#include <utility>
+#include <vector>
+
+namespace tidl {
+
+DartCionGeneratorBase::DartCionGeneratorBase(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans) : CionPluginBase(doc, trans) {
+ type_map_ = {
+ {"char", "int"},
+ {"int", "int"},
+ {"short", "int"},
+ {"long", "int"},
+ {"string", "String"},
+ {"bool", "bool"},
+ {"list", "List"},
+ {"array", "List"},
+ {"double", "double"},
+ {"bundle", "Bundle"},
+ {"void", "void"},
+ {"file", "String"}
+ };
+
+ parcel_type_map_ = {
+ {"char", "Byte"},
+ {"int", "Int32"},
+ {"short", "Int16"},
+ {"long", "Int64"},
+ {"string", "String"},
+ {"bool", "Bool"},
+ {"double", "Double"},
+ {"bundle", "Bundle"},
+ {"file", "String"}
+ };
+
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() == Block::TYPE_STRUCTURE) {
+ auto& st = static_cast<const Structure&>(*b);
+ for (const auto& e : st.GetElements()) {
+ auto& type = e->GetType();
+ AddListSerializer(type);
+ }
+ } else {
+ auto& iface = static_cast<const Interface&>(*b);
+ for (const auto& d : iface.GetDeclarations()) {
+ for (const auto& p : d->GetParameters())
+ AddListSerializer(p->GetParameterType().GetBaseType());
+
+ if (d->GetMethodType() == Declaration::MethodType::SYNC)
+ AddListSerializer(d->GetType());
+ }
+ }
+ }
+}
+
+void DartCionGeneratorBase::AddListSerializer(const BaseType& type) {
+ if (type.ToString() != "list" && type.ToString() != "array")
+ return;
+
+ std::string type_name = ConvertTypeToString(type);
+ AddListSerializer(*type.GetMetaType());
+
+ if (list_serializer_.find(type_name) != list_serializer_.end())
+ return;
+
+ list_serializer_[std::move(type_name)] = &type;
+}
+
+void DartCionGeneratorBase::GenAnnotation(std::ofstream& stream) {
+ ReplaceAll(CB_ANNOTATION, "<VERSION>", FULLVER)
+ .Transform([&](std::string str) {
+ return RemoveLine(str);
+ })
+ .Out(stream);
+}
+
+void DartCionGeneratorBase::GenImport(std::ofstream& stream) {
+ stream << GetTransportable().Dart().GenImport() << std::endl;
+}
+
+void DartCionGeneratorBase::GenVersion(std::ofstream& stream) {
+ ReplaceAll(CB_VERSION_DEF, "<VERSION>", FULLVER).Out(stream);
+ stream << NLine(1);
+}
+
+void DartCionGeneratorBase::GenDelegateId(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code;
+ int cnt = 1;
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() != Declaration::MethodType::DELEGATE)
+ continue;
+
+ if (cnt != 1)
+ code += "," + NLine(1);
+
+ std::string name = i->GetID();
+ name[0] = ::tolower(name[0]);
+ code += ReplaceAll(CB_ENUM, {
+ { "<NAME>", name },
+ { "<VALUE>", std::to_string(cnt++) }
+ });
+ }
+ code += ";";
+
+ ReplaceAll(CB_DELEGATE_ID, "<DELEGATE_IDS>", code)
+ .Transform([&](std::string str) { return SmartIndent(str); })
+ .Out(stream);
+}
+
+void DartCionGeneratorBase::GenDelegateId(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenDelegateId(stream, iface);
+ }
+}
+
+void DartCionGeneratorBase::GenMethodId(std::ofstream& stream,
+ const Interface& iface) {
+ std::string code;
+ int cnt = 2;
+ for (const auto& i : iface.GetDeclarations()) {
+ if (i->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ if (cnt != 2)
+ code += "," + NLine(1);
+
+ std::string name = i->GetID();
+ name[0] = ::tolower(name[0]);
+ code += ReplaceAll(CB_ENUM, {
+ { "<NAME>", name },
+ { "<VALUE>", std::to_string(cnt++) }
+ });
+ }
+ code += ";";
+
+ ReplaceAll(CB_METHOD_ID, "<METHOD_IDS>", code)
+ .Transform([&](std::string str) { return SmartIndent(str); })
+ .Out(stream);
+}
+
+void DartCionGeneratorBase::GenMethodId(std::ofstream& stream) {
+ for (auto& b : GetDocument().GetBlocks()) {
+ if (b->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*b);
+ GenMethodId(stream, iface);
+ }
+}
+
+void DartCionGeneratorBase::GenCallbackBase(std::ofstream& stream) {
+ std::string code = IsProxy() ? CB_PROXY_CALLBACK_BASE : CB_STUB_CALLBACK_BASE;
+ stream << SmartIndent(std::move(code));
+}
+
+void DartCionGeneratorBase::GenStructures(std::ofstream& stream) {
+ GenListSerializer(stream);
+
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_STRUCTURE)
+ continue;
+
+ Structure& st = static_cast<Structure&>(*i);
+ GenStructure(stream, st);
+ stream << std::endl;
+ }
+}
+
+void DartCionGeneratorBase::GenListSerializer(std::ofstream& stream) {
+ if (list_serializer_.empty())
+ return;
+
+ ReplaceAll(CB_LIST_SERIALIZER, {
+ { "<SERIALIZE>", GenListSerializerSerialize() },
+ { "<DESERIALIZE>", GenListSerializerDeserialize() }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+std::string DartCionGeneratorBase::GenListSerializerSerialize() {
+ std::string code;
+ for (const auto& iter : list_serializer_) {
+ std::string parcel_write;
+ auto& type = *(iter.second);
+ if (type.GetMetaType()->IsUserDefinedType()) {
+ parcel_write = ReplaceAll(CB_USER_DEFINED_PARCEL_WRITE, {
+ { "<NAME>", "value" },
+ { "<PARCEL>", "parcel" }
+ });
+ parcel_write += NLine(1);
+ } else if (type.GetMetaType()->ToString() == "list" ||
+ type.GetMetaType()->ToString() == "array") {
+ parcel_write = ReplaceAll(CB_LIST_PARCEL_WRITE, {
+ { "<NAME>", "value" },
+ { "<PARCEL>", "parcel" }
+ });
+ parcel_write += NLine(1);
+ } else {
+ parcel_write = ReplaceAll(CB_BASE_PARCEL_WRITE, {
+ { "<PARCEL>", "parcel" },
+ { "<PARCEL_TYPE>",
+ ConvertTypeToParcelType(type.GetMetaType()->ToString()) },
+ { "<NAME>", "value" }
+ });
+ parcel_write += NLine(1);
+ }
+
+ code += ReplaceAll(CB_LIST_SERIALIZER_SERIALIZE, {
+ { "<TYPE>", iter.first },
+ { "<VALUE_TYPE>", ConvertTypeToString(*type.GetMetaType()) },
+ { "<PARCEL_WRITE>", parcel_write }
+ });
+ }
+
+ return RemoveLine(code);
+}
+
+std::string DartCionGeneratorBase::GenListSerializerDeserialize() {
+ std::string code;
+ for (const auto& iter : list_serializer_) {
+ std::string parcel_read;
+ auto& type = *(iter.second);
+ if (type.GetMetaType()->IsUserDefinedType()) {
+ parcel_read = "final " + ConvertTypeToString(*type.GetMetaType()) +
+ " value = " + ConvertTypeToString(*type.GetMetaType()) + "();";
+ parcel_read += NLine(1);
+ parcel_read += ReplaceAll(CB_USER_DEFINED_PARCEL_READ, {
+ { "<NAME>", "value" },
+ {" <PARCEL>", "parcel" }
+ });
+ } else if (type.GetMetaType()->ToString() == "list" ||
+ type.GetMetaType()->ToString() == "array") {
+ parcel_read = "final " + ConvertTypeToString(*type.GetMetaType()) +
+ " value = [];";
+ parcel_read += NLine(1);
+ parcel_read += ReplaceAll(CB_LIST_PARCEL_READ, {
+ { "<NAME>", "value" },
+ { "<PARCEL>", "parcel" }
+ });
+ } else {
+ parcel_read = "final " + ConvertTypeToString(*type.GetMetaType()) + " ";
+ parcel_read += ReplaceAll(CB_BASE_PARCEL_READ, {
+ { "<PARCEL>", "parcel" },
+ { "<PARCEL_TYPE>",
+ ConvertTypeToParcelType(type.GetMetaType()->ToString()) },
+ { "<NAME>", "value" }
+ });
+ }
+
+ code += ReplaceAll(CB_LIST_SERIALIZER_DESERIALIZE, {
+ { "<TYPE>", iter.first },
+ { "<PARCEL_READ>", parcel_read }
+ });
+ }
+
+ return RemoveLine(code);
+}
+
+void DartCionGeneratorBase::GenStructure(std::ofstream& stream,
+ const Structure& st) {
+ auto& elms = st.GetElements();
+ ReplaceAll(CB_STRUCTURE_BASE, {
+ { "<NAME>", GetClassName(st.GetID()) },
+ { "<ELEMENTS>", GenBaseElements(elms) },
+ { "<PARCEL_WRITE>", GenBaseParcelWrite(elms) },
+ { "<PARCEL_READ>", GenBaseParcelRead(elms) }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+std::string DartCionGeneratorBase::GenBaseElements(const Elements& elms) {
+ std::string code;
+ for (const auto& elm : elms) {
+ if (!code.empty())
+ code += NLine(1);
+
+ auto& type = elm->GetType();
+ auto param_type = ConvertTypeToString(type);
+ code += "/// The " + elm->GetID();
+ code += NLine(1);
+ code += "late " + param_type + " " + elm->GetID() + ";";
+ code += NLine(1);
+ }
+
+ return code;
+}
+
+std::string DartCionGeneratorBase::GenBaseParcelWrite(const Elements& elms) {
+ std::string code;
+ for (const auto& elm : elms) {
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType()) {
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_WRITE, {
+ { "<NAME>", elm->GetID() },
+ { "<PARCEL>", "parcel" }
+ });
+ code += NLine(1);
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += ReplaceAll(CB_LIST_PARCEL_WRITE, {
+ { "<NAME>", elm->GetID() },
+ { "<PARCEL>", "parcel" }
+ });
+ code += NLine(1);
+ } else {
+ code += ReplaceAll(CB_BASE_PARCEL_WRITE, {
+ { "<PARCEL>", "parcel" },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) },
+ { "<NAME>", elm->GetID() }
+ });
+ code += NLine(1);
+ }
+
+ auto private_sharing_code = GetPrivateSharingString(
+ type, "port", elm->GetID());
+ if (!private_sharing_code.empty())
+ code += private_sharing_code + NLine(1);
+ }
+
+ return code;
+}
+
+
+
+std::string DartCionGeneratorBase::GenBaseParcelRead(const Elements& elms) {
+ std::string code;
+ for (const auto& elm : elms) {
+ auto& type = elm->GetType();
+ if (type.IsUserDefinedType()) {
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_READ, {
+ { "<NAME>", elm->GetID() },
+ { "<PARCEL>", "parcel" }
+ });
+ code += NLine(1);
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += ReplaceAll(CB_LIST_PARCEL_READ, {
+ { "<NAME>", elm->GetID() },
+ { "<PARCEL>", "parcel" }
+ });
+ code += NLine(1);
+ } else {
+ code += ReplaceAll(CB_BASE_PARCEL_READ, {
+ { "<PARCEL>", "parcel" },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) },
+ { "<NAME>", elm->GetID() }
+ });
+ code += NLine(1);
+ }
+ }
+
+ return code;
+}
+
+std::string DartCionGeneratorBase::ConvertTypeToString(const BaseType& type) {
+ if (type.IsUserDefinedType())
+ return type.ToString();
+
+ if (type.GetMetaType() != nullptr)
+ return type_map_[type.ToString()] + "<" +
+ ConvertTypeToString(*(type.GetMetaType())) + ">";
+
+ return type_map_[type.ToString()];
+}
+
+std::string DartCionGeneratorBase::ConvertTypeToParcelType(const std::string& key) {
+ return parcel_type_map_[key];
+}
+
+std::string DartCionGeneratorBase::Tab(int cnt) {
+ std::string t;
+ for (int i = 0; i < cnt; i++)
+ t += " ";
+
+ return t;
+}
+
+std::string DartCionGeneratorBase::NLine(int cnt) {
+ std::string t;
+ for (int i = 0; i < cnt; i++)
+ t += "\n";
+
+ return t;
+}
+
+std::string DartCionGeneratorBase::RemoveSpaces(const std::string& str) {
+ // for annotation
+ if (str.compare(0, 3, "/**") == 0 ||
+ str.compare(0, 2, " *") == 0 ||
+ str.compare(0, 3, " */") == 0)
+ return str;
+
+ std::size_t found = str.find_first_not_of(' ');
+ if (found == std::string::npos)
+ return "";
+
+ return str.substr(found, str.size() - found);
+}
+
+std::string DartCionGeneratorBase::Trim(const std::string& str) {
+ // for annotation
+ if (str.compare(0, 3, "/**") == 0 ||
+ str.compare(0, 2, " *") == 0 ||
+ str.compare(0, 3, " */") == 0)
+ return str;
+
+ std::size_t first = str.find_first_not_of(" \t\r\n");
+ if (first == std::string::npos)
+ return str;
+
+ std::size_t last = str.find_last_not_of(" \t\r\n");
+ return str.substr(first, (last - first + 1));
+}
+
+std::string DartCionGeneratorBase::RemoveLine(std::string lines,
+ unsigned int line_num) {
+ std::stringstream ss(lines);
+ std::string result;
+ std::string line;
+ unsigned int line_count = 0;
+
+ while (std::getline(ss, line, '\n')) {
+ line_count++;
+ if (line_num == line_count)
+ continue;
+
+ result += Trim(line);
+ result += NLine(1);
+ }
+
+ return result;
+}
+
+std::string DartCionGeneratorBase::SmartIndent(std::string lines) {
+ std::stringstream stream(lines);
+ std::string next_line;
+ std::string line;
+ std::string tab;
+ std::string line_back;
+ std::string code;
+ unsigned int line_count = 0;
+ int tab_size = 0;
+ std::stack<int> prev_tab_size;
+ bool tab_once = false;
+ bool continuous = false;
+ bool enum_block = false;
+
+ while (std::getline(stream, next_line, '\n')) {
+ next_line = RemoveSpaces(std::move(next_line));
+ line_count++;
+ if (line_count == 1) {
+ line = Trim(next_line);
+ continue;
+ }
+
+ tab.clear();
+ // Checks whether the brace is end or not.
+ if (line.find_first_of("}") < line.find_first_of("{"))
+ tab_size--;
+
+ // Set tab
+ if (line.length() > 0)
+ tab += Tab(tab_size);
+
+ // Set tab for if statement or for loop or while loop
+ if (tab_once) {
+ tab += Tab(1);
+ tab_once = false;
+ }
+
+ if (continuous) {
+ tab += Tab(2);
+ continuous = false;
+ }
+
+ if (line.front() == ':')
+ tab += Tab(2);
+
+ // Checks whether switch case is end or not.
+ line_back = "__INVALID__";
+ if (line.length() > 0)
+ line_back = line.back();
+
+ if (!prev_tab_size.empty() && prev_tab_size.top() == (tab_size - 1) &&
+ line_back == "}") {
+ prev_tab_size.pop();
+ tab_size--;
+ enum_block = false;
+ }
+
+ if (line.empty() || std::all_of(line.begin(), line.end(), isspace)) {
+ std::string new_line = std::move(Trim(next_line));
+ if (new_line.empty() || new_line.find('}') != std::string::npos ||
+ std::all_of(new_line.begin(), new_line.end(), isspace)) {
+ line = std::move(new_line);
+ continue;
+ }
+
+ code += tab + line + NLine(1);
+ } else {
+ if (line.compare(0, 2, " *") != 0)
+ code += tab;
+
+ code += line + NLine(1);
+ }
+
+ // Checks whether the brace is starting or not
+ if (line_back == "{" ) {
+ tab_size++;
+ if (line.find("enum ") != std::string::npos)
+ enum_block = true;
+ }
+
+ if (line_back != "{") {
+ // Checks whether if statement or for loop or while loop without braces is starting or not.
+ if (line.find("if (") != std::string::npos ||
+ line.find("for (") != std::string::npos ||
+ line.find("while (") != std::string::npos)
+ tab_once = true;
+
+ /// Checks whether switch case is starting or not.
+ if ((line.find("case ") != std::string::npos && line_back == ":") ||
+ line.find("default:") != std::string::npos) {
+ tab_size++;
+
+ prev_tab_size.push(tab_size - 1);
+ }
+
+ if (!enum_block && line_back == ",")
+ continuous = true;
+ }
+
+ line = std::move(Trim(next_line));
+ }
+
+ code += line + NLine(1);
+ return code;
+}
+
+std::string DartCionGeneratorBase::GetClassName(std::string name) {
+ name[0] = ::toupper(name[0]);
+ return name;
+}
+
+std::string DartCionGeneratorBase::GetFullNameFromType(const BaseType& type,
+ const Interface& iface) {
+ std::string str;
+ if (IsDelegateType(iface, type))
+ str += iface.GetID() + "_";
+
+ str += type.ToString();
+
+ if (type.GetMetaType() != nullptr) {
+ str += "_";
+ str += GetFullNameFromType(*type.GetMetaType(), iface);
+ } else if (type.GetKeyType() != nullptr) {
+ str += "_";
+ str += GetFullNameFromType(*type.GetKeyType(), iface);
+ str += "_";
+ str += GetFullNameFromType(*type.GetValueType(), iface);
+ }
+
+ return str;
+}
+
+bool DartCionGeneratorBase::HasFile(const Interface& iface) {
+ for (const auto& d : iface.GetDeclarations()) {
+ for (const auto& p : d->GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ auto name = GetFullNameFromType(type, iface);
+ if (name == "file" || name == "list_file" || name == "array_file")
+ return true;
+ }
+ }
+
+ return false;
+}
+
+std::string DartCionGeneratorBase::GetPrivateSharingString(const BaseType& type,
+ const std::string& port, const std::string& arg) {
+ std::string code;
+ if (type.ToString() == "list" || type.ToString() == "array") {
+ if (type.GetMetaType() != nullptr &&
+ type.GetMetaType()->ToString() == "file") {
+ code = ReplaceAll(CB_LIST_FILE_SET_PRIVATE_SHARING, {
+ { "<PORT>", port },
+ { "<ARG>", arg }
+ });
+ }
+ } else if (type.ToString() == "file") {
+ code = ReplaceAll(CB_FILE_SET_PRIVATE_SHARING, {
+ { "<PORT>", port },
+ { "<ARG>", arg }
+ });
+ }
+
+ return code;
+}
+
+} // namespace tidl
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_DART_CION_GEN_BASE_H_
+#define IDLC_GEN_DART_CION_GEN_BASE_H_
+
+#include <map>
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+#include "idlc/ast/structure.h"
+#include "idlc/ast/type.h"
+#include "idlc/gen/generator.h"
+
+#include "idlc/gen_cion/cion_plugin_base.h"
+
+namespace tidl {
+
+class DartCionGeneratorBase : public CionPluginBase {
+ public:
+ explicit DartCionGeneratorBase(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans);
+ virtual ~DartCionGeneratorBase() = default;
+
+ void GenAnnotation(std::ofstream& stream);
+ void GenImport(std::ofstream& stream);
+ void GenVersion(std::ofstream& stream);
+ void GenDelegateId(std::ofstream& stream);
+ void GenMethodId(std::ofstream& stream);
+ void GenCallbackBase(std::ofstream& stream);
+ void GenStructures(std::ofstream& stream);
+
+ std::string ConvertTypeToParcelType(const std::string& key);
+ std::string ConvertTypeToString(const BaseType& type);
+ std::string GetClassName(std::string name);
+ std::string NLine(int cnt);
+ std::string RemoveLine(std::string lines, unsigned int line_num = 1);
+ std::string RemoveSpaces(const std::string& str);
+ std::string SmartIndent(std::string lines);
+ std::string Tab(int cnt);
+ std::string Trim(const std::string& str);
+
+ bool HasFile(const Interface& iface);
+ std::string GetPrivateSharingString(const BaseType& type,
+ const std::string& port, const std::string& arg);
+
+ private:
+ void AddListSerializer(const BaseType& type);
+ void GenListSerializer(std::ofstream& stream);
+ std::string GenListSerializerSerialize();
+ std::string GenListSerializerDeserialize();
+ void GenStructure(std::ofstream& stream, const Structure& st);
+ std::string GenBaseElements(const Elements& elms);
+ std::string GenBaseParcelWrite(const Elements& elms);
+ std::string GenBaseParcelRead(const Elements& elms);
+ void GenDelegateId(std::ofstream& stream, const Interface& iface);
+ void GenMethodId(std::ofstream& stream, const Interface& iface);
+ std::string GetFullNameFromType(const BaseType& type,
+ const Interface& iface);
+
+ protected:
+ const int TAB_SIZE = 2;
+
+ private:
+ std::map<std::string, std::string> type_map_;
+ std::map<std::string, std::string> parcel_type_map_;
+ std::unordered_map<std::string, const BaseType*> list_serializer_;
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_DART_GEN_BASE_H_
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_DART_CION_GEN_BASE_CB_H_
+#define IDLC_GEN_DART_CION_GEN_BASE_CB_H_
+
+namespace tidl {
+
+/**
+ * <VERSION> The TIDLC version.
+ */
+constexpr const char CB_ANNOTATION[] =
+R"__dart_cb(
+/// Generated by tidlc <VERSION>
+
+// ignore_for_file: public_member_api_docs, omit_local_variable_types
+)__dart_cb";
+
+/**
+ * <LOG_TAG> The log tag.
+ */
+constexpr const char CB_LOG_TAG[] =
+R"__dart_cb(const String _logTag = '<LOG_TAG>';)__dart_cb";
+
+/**
+ * <VERSION> The TIDLC version.
+ */
+constexpr const char CB_VERSION_DEF[] =
+R"__dart_cb(const String _tidlVersion = '<VERSION>';)__dart_cb";
+
+/**
+ * <METHOD_IDS> The method IDs.
+ */
+constexpr const char CB_METHOD_ID[] =
+R"__dart_cb(
+enum _MethodId {
+ result(0),
+ callback(1),
+ <METHOD_IDS>
+
+ const _MethodId(this.id);
+ final int id;
+}
+)__dart_cb";
+
+/**
+ * <DELEGATE_IDS> The delegate IDs.
+ */
+constexpr const char CB_DELEGATE_ID[] =
+R"__dart_cb(
+enum _DelegateId {
+ <DELEGATE_IDS>
+
+ const _DelegateId(this.id);
+ final int id;
+}
+)__dart_cb";
+
+/**
+ * <NAME> The name of the enumeration.
+ * <VALUE> The value of the enumeration.
+ */
+constexpr const char CB_ENUM[] =
+R"__dart_cb(<NAME>(<VALUE>))__dart_cb";
+
+constexpr const char CB_PROXY_CALLBACK_BASE[] =
+R"__dart_cb(
+abstract class _Delegate extends Parcelable {
+ _Delegate(this.id, this.once, this.callback) {
+ sequenceId = sequenceNum++;
+ }
+
+ int id = 0;
+ bool once = false;
+ int sequenceId = 0;
+ Function callback;
+ static int sequenceNum = 0;
+
+ Future<void> onReceivedEvent(Parcel parcel);
+
+ @override
+ void serialize(Parcel parcel) {
+ parcel.writeInt32(id);
+ parcel.writeInt32(sequenceId);
+ parcel.writeBool(once);
+ }
+
+ @override
+ void deserialize(Parcel parcel) {
+ id = parcel.readInt32();
+ sequenceId = parcel.readInt32();
+ once = parcel.readBool();
+ }
+}
+)__dart_cb";
+
+constexpr const char CB_STUB_CALLBACK_BASE[] =
+R"__dart_cb(
+abstract class _Delegate extends Parcelable {
+ _Delegate(this.id, this.once);
+
+ int id = 0;
+ bool once = false;
+ int sequenceId = 0;
+
+ @override
+ void serialize(Parcel parcel) {
+ parcel.writeInt32(id);
+ parcel.writeInt32(sequenceId);
+ parcel.writeBool(once);
+ }
+
+ @override
+ void deserialize(Parcel parcel) {
+ id = parcel.readInt32();
+ sequenceId = parcel.readInt32();
+ once = parcel.readBool();
+ }
+}
+)__dart_cb";
+
+/**
+ * <NAME> The name of the structure.
+ * <ELEMENTS> Elements of the structure.
+ * <PARCEL_WRITE> The implementation to write the data to the parcel.
+ * <PARCEL_READ> The implementation to read the data from the parcel.
+ */
+constexpr const char CB_STRUCTURE_BASE[] =
+R"__dart_cb(
+/// The [<NAME>] class.
+class <NAME> extends Parcelable {
+ /// Constructor for this class.
+ <NAME>();
+
+ /// Constructor for creating a [<NAME>] class from the parcel.
+ <NAME>.fromParcel(Parcel parcel) {
+ deserialize(parcel);
+ }
+
+ <ELEMENTS>
+
+ @override
+ void serialize(Parcel parcel) {
+ <PARCEL_WRITE>
+ }
+
+ @override
+ void deserialize(Parcel parcel) {
+ <PARCEL_READ>
+ }
+}
+)__dart_cb";
+
+/**
+ * <NAME> The variable name of the user defined type.
+ * <PARCEL> The name of the parcel instance.
+ */
+constexpr const char CB_USER_DEFINED_PARCEL_WRITE[] =
+R"__dart_cb(<NAME>.serialize(<PARCEL>);)__dart_cb";
+
+/**
+ * <PARCEL> The name of the parcel instance.
+ * <NAME> The variable name of the list type.
+ */
+constexpr const char CB_LIST_PARCEL_WRITE[] =
+R"__dart_cb(ListSerializer().serialize(<PARCEL>, <NAME>);)__dart_cb";
+
+/**
+ * <PARCEL> The name of the parcel instance.
+ * <PARCEL_TYPE> The type of the parcel of the variable.
+ * <NAME> The variable name of the base type.
+ */
+constexpr const char CB_BASE_PARCEL_WRITE[] =
+R"__dart_cb(<PARCEL>.write<PARCEL_TYPE>(<NAME>);)__dart_cb";
+
+/**
+ * <NAME> The variable name of the user defined type.
+ * <PARCEL> The name of the parcel instance.
+ */
+constexpr const char CB_USER_DEFINED_PARCEL_READ[] =
+R"__dart_cb(<NAME>.deserialize(<PARCEL>);)__dart_cb";
+
+/**
+ * <PARCEL> The name of the parcel instance.
+ * <NAME> The variable name of the list type.
+ */
+constexpr const char CB_LIST_PARCEL_READ[] =
+R"__dart_cb(ListSerializer().deserialize(<PARCEL>, <NAME>);)__dart_cb";
+
+/**
+ * <PARCEL> The name of the parcel instance.
+ * <PARCEL_TYPE> The type of the parcel of the element.
+ * <NAME> The variable name of the base type.
+ */
+constexpr const char CB_BASE_PARCEL_READ[] =
+R"__dart_cb(<NAME> = <PARCEL>.read<PARCEL_TYPE>();)__dart_cb";
+
+/**
+ * <PORT> The rpc port handle.
+ * <ARG> The argument.
+ */
+constexpr const char CB_FILE_SET_PRIVATE_SHARING[] =
+R"__dart_cb(<PORT>.shareFile(<ARG>);)__dart_cb";
+
+/**
+ * <PORT> The rpc port handle.
+ * <ARG> The argument.
+ */
+constexpr const char CB_LIST_FILE_SET_PRIVATE_SHARING[] =
+R"__dart_cb(<PORT>.shareFiles(<ARG>);)__dart_cb";
+
+/**
+ * <SERIALIZE> The implementation to serialize the data to the parcel.
+ * <DESERIALIZE> The implementation to deserialize the data from the parcel.
+ */
+constexpr const char CB_LIST_SERIALIZER[] =
+R"__dart_cb(
+/// The [ListSerializer] class for serializing a list to the parcel.
+class ListSerializer {
+ /// Gets the instance of the [ListSerializer].
+ factory ListSerializer() {
+ return _instance;
+ }
+
+ ListSerializer._internal();
+
+ static final ListSerializer _instance = ListSerializer._internal();
+
+ /// Serailizes the parameter to the parcel.
+ void serialize(Parcel parcel, dynamic param) {
+ switch (param.runtimeType) {
+ <SERIALIZE>
+ default:
+ {
+ return;
+ }
+ }
+ }
+
+ /// Deserializes the parameter from the parcel.
+ void deserialize(Parcel parcel, dynamic param) {
+ switch (param.runtimeType) {
+ <DESERIALIZE>
+ default:
+ {
+ return;
+ }
+ }
+ }
+}
+)__dart_cb";
+
+/**
+ * <TYPE> The data type.
+ * <VALUE_TYPE> The value type of the list element.
+ * <PARCEL_WRITE> The implementation to write the data to the parcel.
+ */
+constexpr const char CB_LIST_SERIALIZER_SERIALIZE[] =
+R"__dart_cb(
+case <TYPE>:
+ {
+ parcel.writeArrayCount(param.length as int);
+ param.forEach((<VALUE_TYPE> value) {
+ <PARCEL_WRITE>
+ });
+ return;
+ }
+)__dart_cb";
+
+/**
+ * <TYPE> The data type.
+ * <PARCEL_READ> The implementation to read the data from the parcel.
+ */
+constexpr const char CB_LIST_SERIALIZER_DESERIALIZE[] =
+R"__dart_cb(
+case <TYPE>:
+ {
+ final int count = parcel.readArrayCount();
+ for (int i = 0; i < count; ++i) {
+ <PARCEL_READ>
+ param.add(value);
+ }
+ return;
+ }
+)__dart_cb";
+
+} // namespace tidl
+
+#endif // IDLC_GEN_DART_CION_GEN_BASE_CB_H_
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/dart_cion_stub_gen.h"
+
+#include "idlc/gen_cion/dart_cion_gen_base_cb.h"
+#include "idlc/gen_cion/dart_cion_stub_gen_cb.h"
+
+namespace tidl {
+
+DartCionStubGen::DartCionStubGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans)
+ : DartCionGeneratorBase(doc, trans) {}
+
+void DartCionStubGen::OnInitGen(std::ofstream& stream) {
+ GenAnnotation(stream);
+ GenImport(stream);
+ GenVersion(stream);
+ GenDelegateId(stream);
+ GenMethodId(stream);
+ GenCallbackBase(stream);
+ GenStructures(stream);
+ GenInterfaces(stream);
+}
+
+void DartCionStubGen::OnFiniGen(std::ofstream& stream) {}
+
+void DartCionStubGen::GenInterfaces(std::ofstream& stream) {
+ for (auto& i : GetDocument().GetBlocks()) {
+ if (i->GetType() != Block::TYPE_INTERFACE)
+ continue;
+
+ auto& iface = static_cast<const Interface&>(*i);
+ GenInterface(stream, iface);
+ }
+}
+
+void DartCionStubGen::GenInterface(std::ofstream& stream, const Interface& iface) {
+ GenServiceBase(stream, iface);
+
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ GenDelegateBase(stream, *d);
+ }
+
+ GenInterfaceBase(stream, iface);
+}
+
+void DartCionStubGen::GenInterfaceBase(std::ofstream& stream,
+ const Interface& iface) {
+ std::string name = iface.GetID();
+ name[0] = ::toupper(name[0]);
+ ReplaceAll(CB_INTERFACE_BASE, {
+ { "<CTOR>", GenInterfaceCtor(iface) },
+ { "<EXTEND_NAME>", GetTransportable().Dart().GenStubExtend() },
+ { "<FILE_RECEIVE>",
+ HasFile(iface) ? GetTransportable().Dart().GenFileRecive() : "" },
+ { "<PARAM_DEF>", GetTransportable().Dart().GenStubParamDef() },
+ { "<SUPER_PARAM>", GetTransportable().Dart().GenStubSuperParam() },
+ { "<INTERFACE_NAME>", name },
+ { "<METHOD_HANDLERS>", GenInterfaceMethodHandlers(iface) },
+ { "<PEER_INFO_T>", GetTransportable().Dart().GenPeerInfo() }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(std::move(str));
+ })
+ .Out(stream);
+}
+
+std::string DartCionStubGen::GenInterfaceCtor(const Interface& iface) {
+ std::string method_handler_table;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ std::string name = d->GetID();
+ name[0] = ::tolower(name[0]);
+ method_handler_table += ReplaceAll(CB_METHOD_HANDLER_TABLE, {
+ { "<METHOD_ID>", name },
+ { "<METHOD_NAME>", d->GetID() }
+ });
+ method_handler_table += NLine(1);
+ }
+
+ std::string attributes;
+ for (const auto& i : iface.GetAttributes()) {
+ if (i->GetKey() == "privilege") {
+ attributes += "addPrivilege('" + i->GetValue() + "');";
+ attributes += NLine(1);
+ } else if (i->GetKey() == "trusted" && i->GetValue() == "true") {
+ attributes += "setTrusted(true);";
+ attributes += NLine(1);
+ }
+ }
+
+ std::string code = std::move(method_handler_table);
+ code += NLine(1);
+ code += attributes;
+ return code;
+}
+
+std::string DartCionStubGen::GenInterfaceMethodHandlers(const Interface& iface) {
+ std::string code;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ code += ReplaceAll(CB_METHOD_HANDLER_BASE, {
+ { "<METHOD_NAME>", d->GetID() },
+ { "<METHOD_HANDLER_PARCEL_READ>", GenMethodHandlerParcelRead(*d) },
+ { "<METHOD_HANDLER_INVOKE>", GenMethodHandlerInvoke(*d) },
+ { "<METHOD_HANDLER_PARCEL_WRITE>", GenMethodHandlerParcelWrite(*d) },
+ });
+ }
+
+ return RemoveLine(code);
+}
+
+std::string DartCionStubGen::GenMethodHandlerParcelRead(const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::IN)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ if (type.IsUserDefinedType()) {
+ code += "final " + ConvertTypeToString(type) + " " + p->GetID() +
+ " = " + ConvertTypeToString(type);
+ code += IsDelegateType(type) ? "(service);" : "();";
+ code += NLine(1);
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_READ, {
+ { "<NAME>", p->GetID() },
+ { "<PARCEL>", "parcel" }
+ });
+ code += NLine(1);
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += "final " + ConvertTypeToString(type) + " " + p->GetID() +
+ " = [];";
+ code += NLine(1);
+ code += ReplaceAll(CB_LIST_PARCEL_READ, {
+ { "<NAME>", p->GetID() },
+ { "<PARCEL>" , "parcel" }
+ });
+ code += NLine(1);
+ } else {
+ code += "final " + ConvertTypeToString(type) + " ";
+ code += ReplaceAll(CB_BASE_PARCEL_READ, {
+ { "<PARCEL>", "parcel" },
+ { "<NAME>", p->GetID() },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) }
+ });
+ code += NLine(1);
+ }
+ }
+
+ return code;
+}
+
+std::string DartCionStubGen::GenMethodHandlerInvoke(const Declaration& decl) {
+ std::string args;
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ if (!args.empty())
+ args += ", ";
+
+ args += p->GetID();
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::OUT)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ if (type.IsUserDefinedType()) {
+ code += "final " + ConvertTypeToString(type) + " " + p->GetID() +
+ " = " + ConvertTypeToString(type) + "();";
+ code += NLine(1);
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += "final " + ConvertTypeToString(type) + " " + p->GetID() +
+ " = [];";
+ code += NLine(1);
+ } else {
+ code += "final " + ConvertTypeToString(type) + " " + p->GetID() + ";";
+ code += NLine(1);
+ }
+ }
+
+ if (decl.GetMethodType() == Declaration::MethodType::SYNC)
+ code += "final " + ConvertTypeToString(decl.GetType()) + " ret = await ";
+
+ code += ReplaceAll(CB_METHOD_HANDLER_INVOKE, {
+ { "<METHOD_NAME>", decl.GetID() },
+ { "<ARGS>", args }
+ });
+ return code;
+}
+
+std::string DartCionStubGen::GenMethodHandlerParcelWrite(const Declaration& decl) {
+ if (decl.GetMethodType() == Declaration::MethodType::ASYNC)
+ return {};
+
+ std::string code = std::move(GenMethodHandlerResultParcelWrite(decl));
+ code += GenMethodHandlerOutParamParcelWrite(decl);
+ code = ReplaceAll(CB_METHOD_HANDLER_PARCEL_WRITE, {
+ { "<PARCEL_WRITE>", code },
+ { "<SEND_ASYNC>", GetTransportable().Dart().GenSendAsync(
+ "result", "service._serverBase", "service.peer") }});
+ return code;
+}
+
+std::string DartCionStubGen::GenMethodHandlerResultParcelWrite(
+ const Declaration& decl) {
+ std::string code;
+ auto& type = decl.GetType();
+ if (type.IsUserDefinedType()) {
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_WRITE, {
+ { "<PARCEL>", "result" },
+ { "<NAME>", "ret" }
+ });
+ code += NLine(1);
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += ReplaceAll(CB_LIST_PARCEL_WRITE, {
+ { "<PARCEL>", "result" },
+ { "<NAME>", "ret" }
+ });
+ code += NLine(1);
+ } else {
+ code += ReplaceAll(CB_BASE_PARCEL_WRITE, {
+ { "<PARCEL>", "result" },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) },
+ { "<NAME>" , "ret" }
+ });
+ code += NLine(1);
+ }
+
+ return code;
+}
+
+std::string DartCionStubGen::GenMethodHandlerOutParamParcelWrite(
+ const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ if (param_type.GetDirection() != ParameterType::Direction::OUT)
+ continue;
+
+ auto& type = param_type.GetBaseType();
+ if (type.IsUserDefinedType()) {
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_WRITE, {
+ { "<PARCEL>", "result" },
+ { "<NAME>", p->GetID() }
+ });
+ code += NLine(1);
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += ReplaceAll(CB_LIST_PARCEL_WRITE, {
+ { "<PARCEL>", "result" },
+ { "<NAME>", p->GetID() }
+ });
+ code += NLine(1);
+ } else {
+ code += ReplaceAll(CB_BASE_PARCEL_WRITE, {
+ { "<PARCEL>", "result" },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) },
+ { "<NAME>" , p->GetID() }
+ });
+ code += NLine(1);
+ }
+ }
+
+ return code;
+}
+
+void DartCionStubGen::GenServiceBase(std::ofstream& stream,
+ const Interface& iface) {
+ ReplaceAll(CB_SERVICE_BASE, {
+ { "<PEER_INFO_T>", GetTransportable().Dart().GenPeerInfo() },
+ { "<FILE_RECEIVE_DECL>",
+ HasFile(iface) ? GetTransportable().Dart().GenFileReciveDef() : "" },
+ { "<METHOD_DECLS>", GenServiceBaseMethodDecls(iface) }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(std::move(RemoveLine(std::move(str))));
+ })
+ .Out(stream);
+}
+
+std::string DartCionStubGen::GenServiceBaseMethodDecls(const Interface& iface) {
+ std::string code;
+ for (const auto& d : iface.GetDeclarations()) {
+ if (d->GetMethodType() == Declaration::MethodType::DELEGATE)
+ continue;
+
+ code += ReplaceAll(CB_METHOD_DECL, {
+ { "<RETURN_TYPE>", ConvertTypeToString(d->GetType()) },
+ { "<METHOD_NAME>", d->GetID() },
+ { "<METHOD_PARAMS>", GenMethodParams(*d) }
+ });
+ code += NLine(1);
+ }
+
+ return code;
+}
+
+std::string DartCionStubGen::GenMethodParams(const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ if (!params.empty())
+ params += ", ";
+
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += ConvertTypeToString(type) + " " + p->GetID();
+ }
+
+ return params;
+}
+
+void DartCionStubGen::GenDelegateBase(std::ofstream& stream,
+ const Declaration& decl) {
+ std::string id = decl.GetID();
+ id[0] = ::tolower(id[0]);
+ ReplaceAll(CB_DELEGATE_BASE, {
+ { "<DELEGATE_NAME>", GetClassName(decl.GetID()) },
+ { "<DELEGATE_ID>", id },
+ { "<DELEGATE_PARAMS>", GenDelegateParams(decl) },
+ { "<SEND_ASYNC>", GetTransportable().Dart().GenSendAsync("parcel",
+ "service._serverBase", "service.peer" ) },
+ { "<DELEGATE_PARCEL_WRITE>", GenDelegateParcelWrite(decl) }
+ })
+ .Transform([&](std::string str) {
+ return SmartIndent(str);
+ })
+ .Out(stream);
+}
+
+std::string DartCionStubGen::GenDelegateParams(const Declaration& decl) {
+ std::string params;
+ for (const auto& p : decl.GetParameters()) {
+ if (!params.empty())
+ params += ", ";
+
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ params += ConvertTypeToString(type) + " " + p->GetID();
+ }
+
+ return params;
+}
+
+std::string DartCionStubGen::GenDelegateParcelWrite(const Declaration& decl) {
+ std::string code;
+ for (const auto& p : decl.GetParameters()) {
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ if (type.IsUserDefinedType()) {
+ code += ReplaceAll(CB_USER_DEFINED_PARCEL_WRITE, {
+ { "<NAME>", p->GetID() },
+ { "<PARCEL>", "parcel" }
+ });
+ code += NLine(1);
+ } else if (type.ToString() == "list" || type.ToString() == "array") {
+ code += ReplaceAll(CB_LIST_PARCEL_WRITE, {
+ { "<NAME>", p->GetID() },
+ { "<PARCEL>", "parcel" }
+ });
+ code += NLine(1);
+ } else {
+ code += ReplaceAll(CB_BASE_PARCEL_WRITE, {
+ { "<PARCEL>", "parcel" },
+ { "<PARCEL_TYPE>", ConvertTypeToParcelType(type.ToString()) },
+ { "<NAME>", p->GetID() }
+ });
+ code += NLine(1);
+ }
+
+ auto private_sharing_code = GetPrivateSharingString(
+ type, "_port?", p->GetID());
+ if (!private_sharing_code.empty())
+ code += private_sharing_code + NLine(1);
+ }
+
+ return code;
+}
+
+} // namespace tidl
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_DART_CION_STUB_GEN_H_
+#define IDLC_GEN_DART_CION_STUB_GEN_H_
+
+#include <memory>
+#include <string>
+
+#include "idlc/gen_cion/dart_cion_gen_base.h"
+
+namespace tidl {
+
+class DartCionStubGen : public DartCionGeneratorBase {
+ public:
+ explicit DartCionStubGen(std::shared_ptr<Document> doc,
+ std::shared_ptr<tidl::Transportable> trans);
+ virtual ~DartCionStubGen() = default;
+
+ void OnInitGen(std::ofstream& stream) override;
+ void OnFiniGen(std::ofstream& stream) override;
+
+ private:
+ void GenInterfaces(std::ofstream& stream);
+ void GenInterface(std::ofstream& stream, const Interface& iface);
+ void GenInterfaceBase(std::ofstream& stream, const Interface& iface);
+ std::string GenInterfaceCtor(const Interface& iface);
+ std::string GenInterfaceMethodHandlers(const Interface& iface);
+ std::string GenMethodHandlerParcelRead(const Declaration& decl);
+ std::string GenMethodHandlerInvoke(const Declaration& decl);
+ std::string GenMethodHandlerParcelWrite(const Declaration& decl);
+ std::string GenMethodHandlerResultParcelWrite(const Declaration& decl);
+ std::string GenMethodHandlerOutParamParcelWrite(const Declaration& decl);
+ void GenServiceBase(std::ofstream& stream, const Interface& iface);
+ std::string GenServiceBaseMethodDecls(const Interface& iface);
+ std::string GenMethodParams(const Declaration& decl);
+ void GenDelegateBase(std::ofstream& stream, const Declaration& decl);
+ std::string GenDelegateParams(const Declaration& decl);
+ std::string GenDelegateParcelWrite(const Declaration& decl);
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_DART_CION_STUB_GEN_H_
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_DART_CION_STUB_GEN_CB_H_
+#define IDLC_GEN_DART_CION_STUB_GEN_CB_H_
+
+namespace tidl {
+
+/**
+ * <METHOD_DECLS> The declarations of methods.
+ */
+constexpr const char CB_SERVICE_BASE[] =
+R"__dart_cb(
+/// Abstract class for creating a service base class for RPC.
+abstract class ServiceBase {
+ /// Constructor for this class.
+ ServiceBase(this.peer);
+
+ /// The PeerInfo of client
+ <PEER_INFO_T>? peer;
+
+ bool _isConnected = false;
+ Server? _serverBase;
+
+ /// Disconnects with the client.
+ void disconnect() {
+ if (peer != null && _isConnected) {
+ _serverBase!.disconnect(peer!);
+ peer = null;
+ _isConnected = false;
+ }
+ }
+
+ /// Accepts the connection request from the client.
+ void accept() {
+ if (peer != null && !_isConnected) {
+ _serverBase!.accept(peer!);
+ _isConnected = true;
+ }
+ }
+
+ /// Rejects the connection request from the client.
+ void reject(String reason) {
+ if (peer != null && !_isConnected) {
+ _serverBase!.reject(peer!, reason);
+ peer = null;
+ }
+ }
+
+
+ /// This method will be called when connection requested from the client
+ Future<void> onConnectionRequest();
+
+ /// This abstract method will be called when the client is disconnected.
+ Future<void> onTerminate();
+ <FILE_RECEIVE_DECL>
+ <METHOD_DECLS>
+}
+)__dart_cb";
+
+/**
+ * <RETURN_TYPE> The return type of the method.
+ * <METHOD_NAME> The name of the method.
+ * <METHOD_PARAMS> The parameters of the method.
+ */
+constexpr const char CB_METHOD_DECL[] =
+R"__dart_cb(
+/// This abstract method will be called when the '<METHOD_NAME>' request is delivered.
+Future<<RETURN_TYPE>> on<METHOD_NAME>(<METHOD_PARAMS>);)__dart_cb";
+
+/**
+ * <DELEGATE_NAME> The name of the delegate.
+ * <DELEGATE_ID> The ID of the delegate.
+ * <DELEGATE_PARAMS> Parameters of the delegate.
+ * <DELEGATE_PARCEL_WRITE> The implementation to write arguments to the parcel.
+ */
+constexpr const char CB_DELEGATE_BASE[] =
+R"__dart_cb(
+/// '<DELEGATE_NAME>' class to invoke the delegate method.
+class <DELEGATE_NAME> extends _Delegate {
+ /// Constructor for this class.
+ <DELEGATE_NAME>(this.service, {bool once = false})
+ : super(_DelegateId.<DELEGATE_ID>.id, once);
+
+ /// The client service.
+ ServiceBase service;
+ bool _wasInvoked = false;
+
+ /// Invokes the delegate method of the client.
+ Future<void> invoke(<DELEGATE_PARAMS>) async {
+ if (service.peer == null) {
+ throw StateError('Must be connected first');
+ }
+
+ if (once && _wasInvoked) {
+ throw Exception('Can be invoked only once');
+ }
+
+ final Parcel parcel = Parcel();
+ parcel.writeInt32(_MethodId.callback.id);
+ serialize(parcel);
+
+ <DELEGATE_PARCEL_WRITE>
+
+ <SEND_ASYNC>
+
+ _wasInvoked = true;
+ }
+}
+)__dart_cb";
+
+/**
+ * <INTERFACE_NAME> The name of the interface.
+ * <CTOR> The implementation of the constructor of the interface.
+ * <METHOD_HANDLERS> The implementation of the method handlers of the interface.
+ */
+constexpr const char CB_INTERFACE_BASE[] =
+R"__dart_cb(
+
+/// This is used when creating a service instance.
+typedef ServiceBuilder = ServiceBase Function(<PEER_INFO_T> peer);
+
+typedef _MethodHandler = Future<void> Function(ServiceBase, Parcel);
+
+/// [<INTERFACE_NAME>] class for RPC.
+class <INTERFACE_NAME> extends <EXTEND_NAME> {
+ /// Constructor for this class.
+ <INTERFACE_NAME>({<PARAM_DEF>required ServiceBuilder serviceBuilder} )
+ : _serviceBuilder = serviceBuilder,
+ super(<SUPER_PARAM>) {
+ <CTOR>
+ }
+
+ /// The indexable collection of [ServiceBase] class.
+ final List<ServiceBase> services = <ServiceBase>[];
+ final Map<int, _MethodHandler> _methodHandlers = <int, _MethodHandler>{};
+ final ServiceBuilder _serviceBuilder;
+
+ /// Listens to the requests for connections.
+ Future<void> start() async {
+ await super.listen(
+ onConnectionRequest: (<PEER_INFO_T> peer) async {
+ final ServiceBase service = _serviceBuilder(peer);
+ service.onConnectionRequest();
+ if (service._isConnected) {
+ service._serverBase = this;
+ services.add(service);
+ }
+ }, onDisconnected: (<PEER_INFO_T> peer) async {
+ for (final ServiceBase service in services) {
+ if (service.peer!.uuid == peer.uuid) {
+ await service.onTerminate();
+ services.remove(service);
+ break;
+ }
+ }
+ }, onReceived:
+ (<PEER_INFO_T> peer, Payload payload, PayloadTransferStatus status) async {
+ ServiceBase? service;
+ for (final ServiceBase s in services) {
+ if (s.peer!.uuid == peer.uuid) {
+ service = s;
+ break;
+ }
+ }
+
+ if (service == null) {
+ return;
+ }
+ <FILE_RECEIVE>
+
+ final Uint8List raw = (payload as DataPayload).data;
+ final Parcel parcel = Parcel.fromRaw(raw);
+
+ final int cmd = parcel.readInt32();
+ if (_methodHandlers.containsKey(cmd)) {
+ await _methodHandlers[cmd]!(service!, parcel);
+ }
+ }
+ );
+ }
+
+ @override
+ Future<void> stop() async {
+ await super.stop();
+ }
+
+ <METHOD_HANDLERS>
+}
+)__dart_cb";
+
+/**
+ * <METHOD_ID> The ID of the method.
+ * <METHOD_NAME> The name of the method.
+ */
+constexpr const char CB_METHOD_HANDLER_TABLE[] =
+R"__dart_cb(_methodHandlers[_MethodId.<METHOD_ID>.id] = _on<METHOD_NAME>Method;)__dart_cb";
+
+/**
+ * <METHOD_NAME> The name of the method.
+ * <METHOD_HANDLER_PARCEL_READ> The implementation to read the arguments from the parcel.
+ * <METHOD_HANDLER_INVOKE> The implementation to invoke the method handle.
+ * <METHOD_HANDLER_PARCEL_WRITE> The implementation to write the result to the parcel.
+ * <METHOD_HANDLER_ARGS_FREE> The implementation to release arguments.
+ */
+constexpr const char CB_METHOD_HANDLER_BASE[] =
+R"__dart_cb(
+Future<void> _on<METHOD_NAME>Method(ServiceBase service, Parcel parcel) async {
+ <METHOD_HANDLER_PARCEL_READ>
+ <METHOD_HANDLER_INVOKE>
+ <METHOD_HANDLER_PARCEL_WRITE>
+}
+)__dart_cb";
+
+/**
+ * <METHOD_NAME> The name of the method.
+ * <ARGS> The arguments of the method.
+ */
+constexpr const char CB_METHOD_HANDLER_INVOKE[] =
+R"__dart_cb(service.on<METHOD_NAME>(<ARGS>);)__dart_cb";
+
+/**
+ * <PARCEL_WRITE> The implementation to write the result to the parcel.
+ */
+constexpr const char CB_METHOD_HANDLER_PARCEL_WRITE[] =
+R"__dart_cb(
+final Parcel result = Parcel();
+final ParcelHeader header = parcel.header;
+final ParcelHeader resultHeader = result.header;
+resultHeader.tag = _tidlVersion;
+resultHeader.sequenceNumber = header.sequenceNumber;
+
+result.writeInt32(_MethodId.result.id);
+<PARCEL_WRITE>
+
+<SEND_ASYNC>
+
+)__dart_cb";
+
+} // namespace tidl
+
+#endif // IDLC_GEN_DART_CION_STUB_GEN_CB_H_
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_CION_DART_TRANSPORTABLE_H_
+#define IDLC_GEN_CION_DART_TRANSPORTABLE_H_
+
+#include <list>
+#include <string>
+
+namespace tidl {
+
+class DartTransportable {
+ public:
+ virtual ~DartTransportable() = default;
+ virtual std::string GenImport() const = 0;
+ virtual std::string GenPeerInfo() const = 0;
+ virtual std::string GenSendAsync(std::string parcel,
+ std::string server, std::string peer) const = 0;
+ virtual std::string GenFileReciveDef() const = 0;
+ virtual std::string GenFileRecive() const = 0;
+
+ virtual std::string GenStubExtend() const = 0;
+ virtual std::string GenStubParamDef() const = 0;
+ virtual std::string GenStubSuperParam() const = 0;
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_CION_DART_TRANSPORTABLE_H_
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "idlc/gen_cion/default_dart_transportable.h"
+
+#include <utility>
+
+#include "idlc/gen/replace_all.h"
+
+namespace {
+constexpr const char ___SEND_ASYNC[] =
+R"__c_cb(
+ final DataPayload dp = DataPayload(<PARCEL_NAME>.asRaw());
+ <SERVER_NAME>!.send(<PEER_NAME>!, dp);
+)__c_cb";
+
+} // namespace
+
+namespace tidl {
+
+std::string DefaultDartTransportable::GenImport() const {
+ return R"__c_cb(
+import 'package:tizen_cion/tizen_cion.dart';
+import 'package:tizen_rpc_port/tizen_rpc_port.dart';
+)__c_cb";
+}
+
+std::string DefaultDartTransportable::GenPeerInfo() const {
+ return "PeerInfo";
+}
+
+std::string DefaultDartTransportable::GenSendAsync(std::string parcel,
+ std::string server, std::string peer) const {
+ return std::string(ReplaceAll(___SEND_ASYNC, {
+ { "<PARCEL_NAME>", parcel },
+ { "<PEER_NAME>", peer },
+ { "<SERVER_NAME>", server } }));
+}
+
+std::string DefaultDartTransportable::GenFileReciveDef() const {
+ return R"__c_cb(
+/// This method will be called when received file payload.
+Future<void> onFilePayloadReceived(FilePayload file, PayloadTransferStatus status);
+)__c_cb";
+}
+
+std::string DefaultDartTransportable::GenFileRecive() const {
+ return R"__c_cb(
+ if (payload.type == PayloadType.file) {
+ service!.onFilePayloadReceived(payload as FilePayload, status);
+ return;
+ }
+)__c_cb";
+}
+
+std::string DefaultDartTransportable::GenStubExtend() const {
+ return "Server";
+}
+
+std::string DefaultDartTransportable::GenStubParamDef() const {
+ return R"__c_cb(String? displayName,
+ SecurityInfo? security,
+)__c_cb";
+}
+
+std::string DefaultDartTransportable::GenStubSuperParam() const {
+ return "'<INTERFACE_NAME>', displayName ?? '', security: security";
+}
+} // namespace tidl
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IDLC_GEN_CION_DEFAULT_DART_TRANSPORTABLE_H_
+#define IDLC_GEN_CION_DEFAULT_DART_TRANSPORTABLE_H_
+
+#include <string>
+
+#include "idlc/gen_cion/dart_transportable.h"
+
+namespace tidl {
+
+class DefaultDartTransportable : public DartTransportable {
+ public:
+ virtual ~DefaultDartTransportable() = default;
+ std::string GenImport() const override;
+ std::string GenPeerInfo() const override;
+ std::string GenSendAsync(std::string parcel,
+ std::string server, std::string peer) const override;
+ std::string GenFileReciveDef() const override;
+ std::string GenFileRecive() const override;
+ std::string GenStubExtend() const override;
+ std::string GenStubParamDef() const override;
+ std::string GenStubSuperParam() const override;
+};
+
+} // namespace tidl
+
+#endif // IDLC_GEN_CION_DEFAULT_DART_TRANSPORTABLE_H_
#include "idlc/gen_cion/default_cpp_transportable.h"
#include "idlc/gen_cion/default_java_transportable.h"
#include "idlc/gen_cion/default_cs_transportable.h"
+#include "idlc/gen_cion/default_dart_transportable.h"
namespace tidl {
Cpp_.reset(new DefaultCppTransportable());
Cs_.reset(new DefaultCsTransportable());
Java_.reset(new DefaultJavaTransportable());
+ Dart_.reset(new DefaultDartTransportable());
} else {
// TODO
}
return *Java_;
}
+const DartTransportable& PluginLoader::Dart() {
+ return *Dart_;
+}
+
} // namespace tidl
const CppTransportable& Cpp() override;
const CsTransportable& Cs() override;
const JavaTransportable& Java() override;
+ const DartTransportable& Dart() override;
private:
std::unique_ptr<CTransportable> C_;
std::unique_ptr<CppTransportable> Cpp_;
std::unique_ptr<CsTransportable> Cs_;
std::unique_ptr<JavaTransportable> Java_;
+ std::unique_ptr<DartTransportable> Dart_;
};
} // namespace tidl
#include "idlc/gen_cion/cpp_transportable.h"
#include "idlc/gen_cion/cs_transportable.h"
#include "idlc/gen_cion/java_transportable.h"
+#include "idlc/gen_cion/dart_transportable.h"
namespace tidl {
virtual const CppTransportable& Cpp() = 0;
virtual const CsTransportable& Cs() = 0;
virtual const JavaTransportable& Java() = 0;
+ virtual const DartTransportable& Dart() = 0;
};
} // namespace tidl
const JavaTransportable& MqttPluginLoader::Java() {
return *Java_;
}
+
+const DartTransportable& MqttPluginLoader::Dart() {
+ return *Dart_;
+}
+
} // namespace tidl
const CppTransportable& Cpp() override;
const CsTransportable& Cs() override;
const JavaTransportable& Java() override;
+ const DartTransportable& Dart() override;
private:
std::unique_ptr<CTransportable> C_;
std::unique_ptr<CppTransportable> Cpp_;
std::unique_ptr<CsTransportable> Cs_;
std::unique_ptr<JavaTransportable> Java_;
+ std::unique_ptr<DartTransportable> Dart_;
};
} // namespace tidl
#include "idlc/gen_cion/cpp_cion_stub_body_gen.h"
#include "idlc/gen_cion/cpp_cion_group_header_gen.h"
#include "idlc/gen_cion/cpp_cion_group_body_gen.h"
+#include "idlc/gen_cion/dart_cion_stub_gen.h"
#include "idlc/gen_cion/plugin_loader.h"
#include "idlc/gen_mqtt_plugin/mqtt_plugin_internal_header_gen.h"
#include "idlc/gen_mqtt_plugin/mqtt_plugin_internal_body_gen.h"
cgen.Run(options->GetOutput(), true);
break;
}
+ case tidl::Options::LANGUAGE_TYPE_DART:
+ {
+ tidl::DartCionStubGen stub(ps.GetDoc(), trans);
+ stub.EnableProxy(false);
+ stub.Run(options->GetOutput() + ".dart");
+ break;
+ }
default:
break;