[cion] Implement Dart stub generator 36/290936/5
authorjusung son <jusung07.son@samsung.com>
Wed, 5 Apr 2023 08:16:11 +0000 (17:16 +0900)
committerjusung son <jusung07.son@samsung.com>
Fri, 7 Apr 2023 07:09:18 +0000 (16:09 +0900)
Change-Id: I3d12e1d358c96bfffd73ec64f1a188961bf3da95
Signed-off-by: jusung son <jusung07.son@samsung.com>
15 files changed:
idlc/gen_cion/dart_cion_gen_base.cc [new file with mode: 0644]
idlc/gen_cion/dart_cion_gen_base.h [new file with mode: 0644]
idlc/gen_cion/dart_cion_gen_base_cb.h [new file with mode: 0644]
idlc/gen_cion/dart_cion_stub_gen.cc [new file with mode: 0644]
idlc/gen_cion/dart_cion_stub_gen.h [new file with mode: 0644]
idlc/gen_cion/dart_cion_stub_gen_cb.h [new file with mode: 0644]
idlc/gen_cion/dart_transportable.h [new file with mode: 0644]
idlc/gen_cion/default_dart_transportable.cc [new file with mode: 0644]
idlc/gen_cion/default_dart_transportable.h [new file with mode: 0644]
idlc/gen_cion/plugin_loader.cc
idlc/gen_cion/plugin_loader.h
idlc/gen_cion/transportable.h
idlc/gen_mqtt_plugin/mqtt_plugin_loader.cc
idlc/gen_mqtt_plugin/mqtt_plugin_loader.h
idlc/main.cc

diff --git a/idlc/gen_cion/dart_cion_gen_base.cc b/idlc/gen_cion/dart_cion_gen_base.cc
new file mode 100644 (file)
index 0000000..c08dda6
--- /dev/null
@@ -0,0 +1,632 @@
+/*
+ * 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
diff --git a/idlc/gen_cion/dart_cion_gen_base.h b/idlc/gen_cion/dart_cion_gen_base.h
new file mode 100644 (file)
index 0000000..0269fba
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * 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_
diff --git a/idlc/gen_cion/dart_cion_gen_base_cb.h b/idlc/gen_cion/dart_cion_gen_base_cb.h
new file mode 100644 (file)
index 0000000..8d58ab5
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+ * 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
diff --git a/idlc/gen_cion/dart_cion_stub_gen.cc b/idlc/gen_cion/dart_cion_stub_gen.cc
new file mode 100644 (file)
index 0000000..fb45b05
--- /dev/null
@@ -0,0 +1,397 @@
+/*
+ * 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
diff --git a/idlc/gen_cion/dart_cion_stub_gen.h b/idlc/gen_cion/dart_cion_stub_gen.h
new file mode 100644 (file)
index 0000000..6152057
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * 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
diff --git a/idlc/gen_cion/dart_cion_stub_gen_cb.h b/idlc/gen_cion/dart_cion_stub_gen_cb.h
new file mode 100644 (file)
index 0000000..a2b0ab5
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ * 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_
diff --git a/idlc/gen_cion/dart_transportable.h b/idlc/gen_cion/dart_transportable.h
new file mode 100644 (file)
index 0000000..5939ad0
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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_
diff --git a/idlc/gen_cion/default_dart_transportable.cc b/idlc/gen_cion/default_dart_transportable.cc
new file mode 100644 (file)
index 0000000..d8d1058
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * 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
diff --git a/idlc/gen_cion/default_dart_transportable.h b/idlc/gen_cion/default_dart_transportable.h
new file mode 100644 (file)
index 0000000..407f392
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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_
index 8b177ce57eee237c93877646999bdd05f8758dc9..1f9313b19362642a2fd50e9e4b1b2de8ba58c10e 100644 (file)
@@ -20,6 +20,7 @@
 #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 {
 
@@ -29,6 +30,7 @@ PluginLoader::PluginLoader(const std::string& plugin_path) {
     Cpp_.reset(new DefaultCppTransportable());
     Cs_.reset(new DefaultCsTransportable());
     Java_.reset(new DefaultJavaTransportable());
+    Dart_.reset(new DefaultDartTransportable());
   } else {
     // TODO
   }
@@ -50,4 +52,8 @@ const JavaTransportable& PluginLoader::Java() {
   return *Java_;
 }
 
+const DartTransportable& PluginLoader::Dart() {
+  return *Dart_;
+}
+
 }  // namespace tidl
index 886134053b70343b93823d48bdae7bc8c21d4a84..bdf9c61970705a3209f0c6c21b5fe999f1320b63 100644 (file)
@@ -32,12 +32,14 @@ class PluginLoader : public Transportable {
   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
index 5556cf8c6d089fab79363c86a0045b5c2f8406e8..c62c8d0997ecdaa1f8099a546000dda0b27ce7a7 100644 (file)
@@ -21,6 +21,7 @@
 #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 {
 
@@ -31,6 +32,7 @@ class Transportable {
   virtual const CppTransportable& Cpp() = 0;
   virtual const CsTransportable& Cs() = 0;
   virtual const JavaTransportable& Java() = 0;
+  virtual const DartTransportable& Dart() = 0;
 };
 
 }  // namespace tidl
index 105bae9db148d2aaf12f7ca1a7cd1914b33c126d..bcb6749e7b97b14dfae658584c6e6fdd0ce59f24 100644 (file)
@@ -53,4 +53,9 @@ const CsTransportable& MqttPluginLoader::Cs() {
 const JavaTransportable& MqttPluginLoader::Java() {
  return *Java_;
 }
+
+const DartTransportable& MqttPluginLoader::Dart() {
+ return *Dart_;
+}
+
 }  // namespace tidl
index 125bb8ca1358b5aec0b93ce51adfa4c0dc99d292..9b3e40cc82aab8b352e1a72723a12bf2af6e2d0d 100644 (file)
@@ -32,12 +32,14 @@ class MqttPluginLoader : public Transportable {
   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
index 839f803f4f67de08696b577c55d863be5dd70b64..38cdc0b0e94702727cafe9199ccbbb51f4bb1d0e 100644 (file)
@@ -59,6 +59,7 @@
 #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"
@@ -133,6 +134,13 @@ void GenerateStubCodes(std::shared_ptr<tidl::Options> options,
       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;