Support Map & Set container for C++ Generator 79/296879/10
authorHwankyu Jhun <h.jhun@samsung.com>
Mon, 7 Aug 2023 05:10:12 +0000 (14:10 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Wed, 9 Aug 2023 08:08:17 +0000 (17:08 +0900)
This patch supports map and set container types.

Change-Id: I9bf1e9164b1b7050b94584194064b8f339d24112
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
idlc/ast/tidlc.yy
idlc/ast/tidlc_y.cpp
idlc/ast/type.cc
idlc/ast/type.h
idlc/gen/version2/cpp_generator_base.cc
idlc/gen/version2/cpp_generator_base_cb.hh
tests/build_tests/tidl/Message_v2test.tidl

index c0d3b0581fac0ded633f2ef686fe424206796f54..7a7d5dfe660af368f6e5a8e5e33675e18ea1f7d6 100644 (file)
@@ -870,6 +870,12 @@ container_type: container_type_name T_META_OPEN base_type T_META_CLOSE {
           ps->ReportError("syntax error. The file should be included in only one container.", @1.begin.line);
         }
 
+        if ($1->ToString() == "set") {
+          if (!tidl::BaseType::IsKeyType($3)) {
+            ps->ReportError("syntax error. The key type should be 'char', 'int', 'short', 'long', 'string', 'bool', 'float' and 'double.", @1.begin.line);
+          }
+        }
+
         $$ = new tidl::BaseType($1->ToString(), $1->GetComments());
         $$->SetMetaType($3);
         delete $1;
@@ -880,6 +886,10 @@ container_type: container_type_name T_META_OPEN base_type T_META_CLOSE {
         ps->ReportError("syntax error. The container type must be \"map\".", @1.begin.line);
         delete $1;
       } else {
+        if (!tidl::BaseType::IsKeyType($3)) {
+          ps->ReportError("syntax error. The key type should be 'char', 'int', 'short', 'long', 'string', 'bool', 'float' and 'double.", @1.begin.line);
+        }
+
         $$ = new tidl::BaseType($1->ToString(), $1->GetComments());
         $$->SetKeyType($3);
         $$->SetValueType($5);
index cdfa45fab61cad8f5dee4b7c43e38a4691f46c5d..a649126d238cb05db9c0315daaeadec509a74604 100644 (file)
@@ -397,7 +397,7 @@ static const yytype_int16 yyrline[] =
      635,   640,   644,   648,   652,   656,   662,   670,   681,   687,
      690,   693,   698,   701,   705,   711,   714,   720,   723,   740,
      743,   747,   751,   755,   759,   763,   767,   771,   781,   785,
-     789,   837,   864,   878,   891,   895,   899,   907
+     789,   837,   864,   884,   901,   905,   909,   917
 };
 #endif
 
@@ -2570,50 +2570,60 @@ yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
           ps->ReportError("syntax error. The file should be included in only one container.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yyloc).begin.line);
         }
 
+        if ((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->ToString() == "set") {
+          if (!tidl::BaseType::IsKeyType((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.b_type))) {
+            ps->ReportError("syntax error. The key type should be 'char', 'int', 'short', 'long', 'string', 'bool', 'float' and 'double.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yyloc).begin.line);
+          }
+        }
+
         ((*yyvalp).b_type) = new tidl::BaseType((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token)->GetComments());
         ((*yyvalp).b_type)->SetMetaType((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.b_type));
         delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.token);
       }
     }
-#line 2579 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+#line 2585 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
     break;
 
   case 93:
-#line 878 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+#line 884 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
                                                                                {
       if ((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token)->ToString() != "map") {
         ps->ReportError("syntax error. The container type must be \"map\".", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yyloc).begin.line);
         delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token);
       } else {
+        if (!tidl::BaseType::IsKeyType((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.b_type))) {
+          ps->ReportError("syntax error. The key type should be 'char', 'int', 'short', 'long', 'string', 'bool', 'float' and 'double.", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yyloc).begin.line);
+        }
+
         ((*yyvalp).b_type) = new tidl::BaseType((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token)->ToString(), (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token)->GetComments());
         ((*yyvalp).b_type)->SetKeyType((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-3)].yystate.yysemantics.yysval.b_type));
         ((*yyvalp).b_type)->SetValueType((YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-1)].yystate.yysemantics.yysval.b_type));
         delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (-5)].yystate.yysemantics.yysval.token);
       }
     }
-#line 2595 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+#line 2605 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
     break;
 
   case 94:
-#line 891 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+#line 901 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
                             {
       ((*yyvalp).token) = new tidl::Token("list", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
       delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
     }
-#line 2604 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+#line 2614 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
     break;
 
   case 95:
-#line 895 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+#line 905 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
               {
       ((*yyvalp).token) = new tidl::Token("array", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
       delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
     }
-#line 2613 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+#line 2623 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
     break;
 
   case 96:
-#line 899 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+#line 909 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
             {
       if (ps->GetVersion() < 2) {
         ps->ReportError("syntax error. \"No identifier\".", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yyloc).begin.line);
@@ -2622,11 +2632,11 @@ yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
       ((*yyvalp).token) = new tidl::Token("map", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
       delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
     }
-#line 2626 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+#line 2636 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
     break;
 
   case 97:
-#line 907 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+#line 917 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
             {
       if (ps->GetVersion() < 2) {
         ps->ReportError("syntax error. \"No identifier\".", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yyloc).begin.line);
@@ -2635,11 +2645,11 @@ yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
       ((*yyvalp).token) = new tidl::Token("set", (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token)->GetComments());
       delete (YY_CAST (yyGLRStackItem const *, yyvsp)[YYFILL (0)].yystate.yysemantics.yysval.token);
     }
-#line 2639 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+#line 2649 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
     break;
 
 
-#line 2643 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+#line 2653 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
 
       default: break;
     }
@@ -4101,7 +4111,7 @@ yyparse (yy::parser& yyparser, tidl::Parser* ps)
 
   // User initialization code.
 yylloc.initialize ();
-#line 4105 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+#line 4115 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
 
 
   if (! yyinitGLRStack (yystackp, YYINITDEPTH))
@@ -4389,7 +4399,7 @@ yypdumpstack (yyGLRStack* yystackp)
 
 
 
-#line 917 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
+#line 927 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc.yy"
 
 
 #include <ctype.h>
@@ -4401,7 +4411,7 @@ void yy::parser::error(const yy::parser::location_type& l,
 }
 
 
-#line 4405 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+#line 4415 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
 
 /*------------------.
 | Report an error.  |
@@ -4417,7 +4427,7 @@ yyerror (const yy::parser::location_type *yylocationp, yy::parser& yyparser, tid
 
 
 namespace yy {
-#line 4421 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+#line 4431 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
 
   /// Build a parser object.
   parser::parser (tidl::Parser* ps_yyarg)
@@ -4505,4 +4515,4 @@ namespace yy {
 
 #endif
 } // yy
-#line 4509 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
+#line 4519 "/opt/data/tizen/public/platform/core/appfw/tidl/idlc/ast/tidlc_y.cpp"
index 7c61c36b7e427b18f4612e74f3dea86b229402e4..4441fe0bc3be86d13f46f7191595ea6a7e06c64b 100644 (file)
@@ -164,6 +164,26 @@ bool BaseType::IsFile(const BaseType* type) {
   return type->ToString() == "file";
 }
 
+bool BaseType::IsKeyType(const BaseType* type) {
+  if (type == nullptr)
+    return false;
+
+  if (type->GetMetaType() != nullptr ||
+      type->GetKeyType() != nullptr)
+    return false;
+
+  if (type->ToString() == "char" ||
+      type->ToString() == "int" ||
+      type->ToString() == "short" ||
+      type->ToString() == "string" ||
+      type->ToString() == "bool" ||
+      type->ToString() == "float" ||
+      type->ToString() == "double")
+    return true;
+
+  return false;
+}
+
 ParameterType::ParameterType(BaseType* type)
     : type_(type),
     dir_(Direction::IN) {
index fce01f2b2af423be06c86598d27c34ea8a09e25d..bb74a87387bd0a9073e2fb9b7db08dfc0c25d48b 100644 (file)
@@ -75,6 +75,7 @@ class BaseType : public Token {
   }
 
   static bool IsFile(const BaseType* type);
+  static bool IsKeyType(const BaseType* type);
 
  private:
   std::unique_ptr<BaseType> meta_type_;
index 50b188115dfe7b53886306c84b3ca645f680f1fa..3122e51f1d35e7a0d55ac4069a3fece5bf52d4ec 100644 (file)
@@ -29,6 +29,7 @@ namespace {
 bool IsObject(const BaseType& type) {
   if (type.IsUserDefinedType() ||
       type.GetMetaType() != nullptr ||
+      type.GetKeyType() != nullptr ||
       type.ToString() == "string" ||
       type.ToString() == "bundle" ||
       type.ToString() == "file")
@@ -56,7 +57,9 @@ CppGeneratorBase::CppGeneratorBase(std::shared_ptr<Document> doc,
     {"file", "File"},
     {"bundle", "Bundle"},
     {"void", "void"},
-    {"array", "std::vector"}
+    {"array", "std::vector"},
+    {"map", "std::map"},
+    {"set", "std::set"}
   };
 
   parcel_type_map_ = {
@@ -241,6 +244,12 @@ std::string CppGeneratorBase::ConvertTypeToString(const BaseType& type,
         ConvertTypeToString(*(type.GetMetaType())) + ">";
   }
 
+  if (type.GetKeyType() != nullptr && type.GetValueType() != nullptr) {
+    return type_map_[type.ToString()] + "<" +
+           ConvertTypeToString(*(type.GetKeyType())) + ", " +
+           ConvertTypeToString(*(type.GetValueType())) + ">";
+  }
+
   return type_map_[type.ToString()];
 }
 
@@ -495,6 +504,9 @@ void CppGeneratorBase::InitUnitTypes(bool use_file) {
           AddUnitType("delegate",
               BaseType(iface.GetID() + "::CallbackBase", "", true));
           AddUnitType(decl->GetID(), BaseType(decl->GetID(), "", true));
+        } else if (decl->GetMethodType() == Declaration::MethodType::SYNC) {
+          auto& type = decl->GetType();
+          AddUnitType(type.GetFullName(false), BaseType(type));
         }
 
         for (const auto& param : decl->GetParameters()) {
@@ -519,6 +531,16 @@ void CppGeneratorBase::AddUnitType(std::string name, BaseType type) {
     AddUnitType(meta_type->GetFullName(false), BaseType(*meta_type));
   }
 
+  if (type.GetKeyType() != nullptr) {
+    auto key_type = type.GetKeyType();
+    AddUnitType(key_type->GetFullName(false), BaseType(*key_type));
+
+    if (type.GetValueType() != nullptr) {
+      auto value_type = type.GetValueType();
+      AddUnitType(value_type->GetFullName(false), BaseType(*value_type));
+    }
+  }
+
   unit_types_[std::move(name)] = std::move(type);
 }
 
@@ -583,7 +605,8 @@ std::string CppGeneratorBase::GenUnitSerializerBodies() {
 
 std::string CppGeneratorBase::GenUnitImplSerializer(const BaseType& type) {
   std::string code;
-  if (type.IsUserDefinedType() || type.GetMetaType() != nullptr) {
+  if (type.IsUserDefinedType() || type.GetMetaType() != nullptr ||
+      type.GetKeyType() != nullptr) {
     if (IsDelegateType(type)) {
       code = CB_UNIT_IMPL_SERIALIZER_DELEGATE;
     } else {
@@ -612,6 +635,10 @@ std::string CppGeneratorBase::GenUnitMapWrite(const BaseType& type) {
     code = CB_UNIT_MAP_ARRAY_WRITE;
   } else if (type.ToString() == "list") {
     code = CB_UNIT_MAP_LIST_WRITE;
+  } else if (type.ToString() == "map") {
+    code = CB_UNIT_MAP_MAP_WRITE;
+  } else if (type.ToString() == "set") {
+    code = CB_UNIT_MAP_SET_WRITE;
   } else {
     for (auto& block : GetDocument().GetBlocks()) {
       if (block->GetType() == Block::TYPE_STRUCTURE) {
@@ -631,7 +658,8 @@ std::string CppGeneratorBase::GenUnitMapWrite(const BaseType& type) {
 
 std::string CppGeneratorBase::GenUnitImplDeserializer(const BaseType& type) {
   std::string code;
-  if (type.IsUserDefinedType() || type.GetMetaType() != nullptr) {
+  if (type.IsUserDefinedType() || type.GetMetaType() != nullptr ||
+      type.GetKeyType() != nullptr) {
     if (IsDelegateType(type)) {
       code = ReplaceAll(CB_UNIT_IMPL_DESERIALIZER_DELEGATE)
           .Change("<IFACE_NAME>", GetInterfaceNameFromDelegate(type));
@@ -664,6 +692,13 @@ std::string CppGeneratorBase::GenUnitMapRead(const BaseType& type) {
   } else if (type.ToString() == "list") {
     code = ReplaceAll(CB_UNIT_MAP_LIST_READ)
         .Change("<TYPE>", ConvertTypeToString(*type.GetMetaType()));
+  } else if (type.ToString() == "map") {
+    code = ReplaceAll(CB_UNIT_MAP_MAP_READ)
+        .Change("<KEY_TYPE>", ConvertTypeToString(*type.GetKeyType()))
+        .Change("<VALUE_TYPE>", ConvertTypeToString(*type.GetValueType()));
+  } else if (type.ToString() == "set") {
+    code = ReplaceAll(CB_UNIT_MAP_SET_READ)
+        .Change("<KEY_TYPE>", ConvertTypeToString(*type.GetMetaType()));
   } else {
     for (auto& block : GetDocument().GetBlocks()) {
       if (block->GetType() == Block::TYPE_STRUCTURE) {
index acc1b90b98d668f3ce4dc3169463c6a3b2da7f72..fc4148f4c3ff216345d55144858dda1d4a5730f7 100644 (file)
@@ -41,7 +41,9 @@ R"__cpp_cb(
 #include <rpc-port.h>
 #include <rpc-port-parcel.h>
 
+#include <map>
 #include <memory>
+#include <set>
 #include <string>
 #include <stdexcept>
 #include <utility>
@@ -59,8 +61,10 @@ R"__cpp_cb(
 #include <atomic>
 #include <functional>
 #include <list>
+#include <map>
 #include <memory>
 #include <mutex>
+#include <set>
 #include <string>
 #include <vector>
 #include <unordered_map>
@@ -537,6 +541,28 @@ for (auto& data : value)
   unit_map.Write(std::to_string(index++), data);
 )__cpp_cb";
 
+constexpr const char CB_UNIT_MAP_MAP_WRITE[] =
+R"__cpp_cb(
+unit_map.Write("size", static_cast<int>(value.size() & INT_MAX));
+
+int index = 0;
+for (auto& iter : value) {
+  auto& key = iter.first;
+  unit_map.Write("key-" + std::to_string(index), key);
+  auto& val = iter.second;
+  unit_map.Write("value-" + std::to_string(index++), val);
+}
+)__cpp_cb";
+
+constexpr const char CB_UNIT_MAP_SET_WRITE[] =
+R"__cpp_cb(
+unit_map.Write("size", static_cast<int>(value.size() & INT_MAX));
+
+int index = 0;
+for (auto& key : value)
+  unit_map.Write("key-" + std::to_string(index++), key);
+)__cpp_cb";
+
 /**
  * <NAME> The name of the element of the value.
  */
@@ -624,6 +650,39 @@ for (int index = 0; index < tmp_length; ++index) {
 }
 )__cpp_cb";
 
+/**
+ * <KEY_TYPE> The type of the key of the map.
+ * <VALUE_TYPE> The type of the value of the map.
+ */
+constexpr const char CB_UNIT_MAP_MAP_READ[] =
+R"__cpp_cb(
+int tmp_size = 0;
+unit_map.Read("size", tmp_size);
+
+for (int index = 0; index < tmp_size; ++index) {
+  <KEY_TYPE> tmp_key;
+  unit_map.Read("key-" + std::to_string(index), tmp_key);
+  <VALUE_TYPE> tmp_value;
+  unit_map.Read("value-" + std::to_string(index), tmp_value);
+  value[tmp_key] = tmp_value;
+}
+)__cpp_cb";
+
+/**
+ * <KEY_TYPE> The type of the key of the map.
+ */
+constexpr const char CB_UNIT_MAP_SET_READ[] =
+R"__cpp_cb(
+int tmp_size = 0;
+unit_map.Read("size", tmp_size);
+
+for (int index = 0; index < tmp_size; ++index) {
+  <KEY_TYPE> tmp_key;
+  unit_map.Read("key-" + std::to_string(index), tmp_key);
+  value.insert(tmp_key);
+}
+)__cpp_cb";
+
 /**
  * <NAME> The name of the element of the value.
  */
index 5bfae2b367d3fee59461b65ae4c144a701a21032..d1e1f0e56184e044aa4c9690c8618166d3b6dbe3 100644 (file)
@@ -3,6 +3,8 @@ protocol 2
 struct Envelope {
   list<string> string_list;
   array<bundle> bundle_array;
+  map<string, int> string_int_map;
+  set<string> string_iset;
 }
 
 interface Message {
@@ -13,4 +15,5 @@ interface Message {
   int Send(string msg);
   int SendFiles(list<file> files);
   int SendFile(file f);
+  int SendEnvelope(Envelope envelope);
 }