Implement int8, uint8, int16, uint16, int64, uint64 types

This sw did not support uint8 type, which is needed by the upcoming
driver CalibrationBox within cla-sysrepo, so we implemented uint8 and
other types in TODO sections.

Creating leaf_data_XXX_classes for all types would result in a lot of
redundant code so the base class was turned into a template and the type
is passed through the template argument.

Change-Id: I866a3933fe21ea7844299556e5aaf39b3e40e92f
Co-Authored-By: Jan Kundrát <jan.kundrat@cesnet.cz>
diff --git a/src/ast_commands.hpp b/src/ast_commands.hpp
index f4cd0a9..32dba64 100644
--- a/src/ast_commands.hpp
+++ b/src/ast_commands.hpp
@@ -21,10 +21,16 @@
 using x3::char_;
 using x3::double_;
 using x3::expect;
-using x3::int_;
+using x3::int8;
+using x3::int16;
+using x3::int32;
+using x3::int64;
 using x3::lexeme;
 using x3::lit;
-using x3::uint_;
+using x3::uint8;
+using x3::uint16;
+using x3::uint32;
+using x3::uint64;
 
 struct parser_context_tag;
 
diff --git a/src/ast_handlers.hpp b/src/ast_handlers.hpp
index dd80889..69af5ac 100644
--- a/src/ast_handlers.hpp
+++ b/src/ast_handlers.hpp
@@ -395,11 +395,12 @@
     }
 };
 
+template<yang::LeafDataTypes TYPE>
 struct leaf_data_base_class {
     yang::LeafDataTypes m_type;
 
-    leaf_data_base_class(yang::LeafDataTypes type)
-        : m_type(type)
+    leaf_data_base_class()
+        : m_type(TYPE)
     {
     }
 
@@ -421,11 +422,10 @@
     }
 };
 
-struct leaf_data_enum_class : leaf_data_base_class {
-    leaf_data_enum_class()
-        : leaf_data_base_class(yang::LeafDataTypes::Enum)
-    {
-    }
+struct leaf_data_binary_data_class;
+
+struct leaf_data_enum_class : leaf_data_base_class<yang::LeafDataTypes::Enum> {
+    using leaf_data_base_class::leaf_data_base_class;
 
     template <typename T, typename Iterator, typename Context>
     void on_success(Iterator const& start, Iterator const& end, T& ast, Context const& context)
@@ -449,57 +449,10 @@
     }
 };
 
-struct leaf_data_decimal_class : leaf_data_base_class {
-    leaf_data_decimal_class()
-        : leaf_data_base_class(yang::LeafDataTypes::Decimal)
-    {
-    }
-};
-
-struct leaf_data_bool_class : leaf_data_base_class {
-    leaf_data_bool_class()
-        : leaf_data_base_class(yang::LeafDataTypes::Bool)
-    {
-    }
-};
-
-struct leaf_data_int_class : leaf_data_base_class {
-    leaf_data_int_class()
-        : leaf_data_base_class(yang::LeafDataTypes::Int)
-    {
-    }
-};
-
-struct leaf_data_uint_class : leaf_data_base_class {
-    leaf_data_uint_class()
-        : leaf_data_base_class(yang::LeafDataTypes::Uint)
-    {
-    }
-};
-
-struct leaf_data_string_class : leaf_data_base_class {
-    leaf_data_string_class()
-        : leaf_data_base_class(yang::LeafDataTypes::String)
-    {
-    }
-};
-
-struct leaf_data_binary_data_class;
-
-struct leaf_data_binary_class : leaf_data_base_class {
-    leaf_data_binary_class()
-        : leaf_data_base_class(yang::LeafDataTypes::Binary)
-    {
-    }
-};
-
 struct leaf_data_identityRef_data_class;
 
-struct leaf_data_identityRef_class : leaf_data_base_class {
-    leaf_data_identityRef_class()
-        : leaf_data_base_class(yang::LeafDataTypes::IdentityRef)
-    {
-    }
+struct leaf_data_identityRef_class : leaf_data_base_class<yang::LeafDataTypes::IdentityRef> {
+    using leaf_data_base_class::leaf_data_base_class;
 
     template <typename T, typename Iterator, typename Context>
     void on_success(Iterator const& start, Iterator const& end, T& ast, Context const& context)
diff --git a/src/ast_values.hpp b/src/ast_values.hpp
index 350fc8d..44e98af 100644
--- a/src/ast_values.hpp
+++ b/src/ast_values.hpp
@@ -43,6 +43,12 @@
                                   identityRef_,
                                   double,
                                   bool,
+                                  int8_t,
+                                  uint8_t,
+                                  int16_t,
+                                  uint16_t,
                                   int32_t,
                                   uint32_t,
+                                  int64_t,
+                                  uint64_t,
                                   std::string>;
diff --git a/src/grammars.hpp b/src/grammars.hpp
index 583a960..276e716 100644
--- a/src/grammars.hpp
+++ b/src/grammars.hpp
@@ -39,13 +39,19 @@
 
 x3::rule<leaf_data_class, leaf_data_> const leaf_data = "leaf_data";
 x3::rule<leaf_data_enum_class, enum_> const leaf_data_enum = "leaf_data_enum";
-x3::rule<leaf_data_decimal_class, double> const leaf_data_decimal = "leaf_data_decimal";
-x3::rule<leaf_data_bool_class, bool> const leaf_data_bool = "leaf_data_bool";
-x3::rule<leaf_data_int_class, int32_t> const leaf_data_int = "leaf_data_int";
-x3::rule<leaf_data_uint_class, uint32_t> const leaf_data_uint = "leaf_data_uint";
-x3::rule<leaf_data_string_class, std::string> const leaf_data_string = "leaf_data_string";
+x3::rule<leaf_data_base_class<yang::LeafDataTypes::Decimal>, double> const leaf_data_decimal = "leaf_data_decimal";
+x3::rule<leaf_data_base_class<yang::LeafDataTypes::Bool>, bool> const leaf_data_bool = "leaf_data_bool";
+x3::rule<leaf_data_base_class<yang::LeafDataTypes::Int8>, int8_t> const leaf_data_int8 = "leaf_data_int8";
+x3::rule<leaf_data_base_class<yang::LeafDataTypes::Uint8>, uint8_t> const leaf_data_uint8 = "leaf_data_uint8";
+x3::rule<leaf_data_base_class<yang::LeafDataTypes::Int16>, int16_t> const leaf_data_int16 = "leaf_data_int16";
+x3::rule<leaf_data_base_class<yang::LeafDataTypes::Uint16>, uint16_t> const leaf_data_uint16 = "leaf_data_uint16";
+x3::rule<leaf_data_base_class<yang::LeafDataTypes::Int32>, int32_t> const leaf_data_int32 = "leaf_data_int32";
+x3::rule<leaf_data_base_class<yang::LeafDataTypes::Uint32>, uint32_t> const leaf_data_uint32 = "leaf_data_uint32";
+x3::rule<leaf_data_base_class<yang::LeafDataTypes::Int64>, int64_t> const leaf_data_int64 = "leaf_data_int64";
+x3::rule<leaf_data_base_class<yang::LeafDataTypes::Uint64>, uint64_t> const leaf_data_uint64 = "leaf_data_uint64";
+x3::rule<leaf_data_base_class<yang::LeafDataTypes::String>, std::string> const leaf_data_string = "leaf_data_string";
 x3::rule<leaf_data_binary_data_class, std::string> const leaf_data_binary_data = "leaf_data_binary_data";
-x3::rule<leaf_data_binary_class, binary_> const leaf_data_binary = "leaf_data_binary";
+x3::rule<leaf_data_base_class<yang::LeafDataTypes::Binary>, binary_> const leaf_data_binary = "leaf_data_binary";
 x3::rule<leaf_data_identityRef_data_class, identityRef_> const leaf_data_identityRef_data = "leaf_data_identityRef_data";
 x3::rule<leaf_data_identityRef_class, identityRef_> const leaf_data_identityRef = "leaf_data_identityRef";
 
@@ -212,10 +218,22 @@
 
 auto const leaf_data_bool_def =
     bool_rule;
-auto const leaf_data_int_def =
-    int_;
-auto const leaf_data_uint_def =
-    uint_;
+auto const leaf_data_int8_def =
+    int8;
+auto const leaf_data_int16_def =
+    int16;
+auto const leaf_data_int32_def =
+    int32;
+auto const leaf_data_int64_def =
+    int64;
+auto const leaf_data_uint8_def =
+    uint8;
+auto const leaf_data_uint16_def =
+    uint16;
+auto const leaf_data_uint32_def =
+    uint32;
+auto const leaf_data_uint64_def =
+    uint64;
 auto const leaf_data_string_def =
     *char_;
 
@@ -240,8 +258,14 @@
     leaf_data_enum |
     leaf_data_decimal |
     leaf_data_bool |
-    leaf_data_int |
-    leaf_data_uint |
+    leaf_data_int8 |
+    leaf_data_int16 |
+    leaf_data_int32 |
+    leaf_data_int64 |
+    leaf_data_uint8 |
+    leaf_data_uint16 |
+    leaf_data_uint32 |
+    leaf_data_uint64 |
     leaf_data_binary |
     leaf_data_identityRef |
     leaf_data_string];
@@ -332,8 +356,14 @@
 BOOST_SPIRIT_DEFINE(leaf_data_enum)
 BOOST_SPIRIT_DEFINE(leaf_data_decimal)
 BOOST_SPIRIT_DEFINE(leaf_data_bool)
-BOOST_SPIRIT_DEFINE(leaf_data_int)
-BOOST_SPIRIT_DEFINE(leaf_data_uint)
+BOOST_SPIRIT_DEFINE(leaf_data_int8)
+BOOST_SPIRIT_DEFINE(leaf_data_int16)
+BOOST_SPIRIT_DEFINE(leaf_data_int32)
+BOOST_SPIRIT_DEFINE(leaf_data_int64)
+BOOST_SPIRIT_DEFINE(leaf_data_uint8)
+BOOST_SPIRIT_DEFINE(leaf_data_uint16)
+BOOST_SPIRIT_DEFINE(leaf_data_uint32)
+BOOST_SPIRIT_DEFINE(leaf_data_uint64)
 BOOST_SPIRIT_DEFINE(leaf_data_string)
 BOOST_SPIRIT_DEFINE(leaf_data_binary_data)
 BOOST_SPIRIT_DEFINE(leaf_data_binary)
diff --git a/src/schema.hpp b/src/schema.hpp
index 87feeaa..145ab07 100644
--- a/src/schema.hpp
+++ b/src/schema.hpp
@@ -27,8 +27,14 @@
     String,
     Decimal,
     Bool,
-    Int,
-    Uint,
+    Int8,
+    Uint8,
+    Int16,
+    Uint16,
+    Int32,
+    Uint32,
+    Int64,
+    Uint64,
     Enum,
     Binary,
     IdentityRef,
diff --git a/src/sysrepo_access.cpp b/src/sysrepo_access.cpp
index 16dfab5..2c80c2d 100644
--- a/src/sysrepo_access.cpp
+++ b/src/sysrepo_access.cpp
@@ -14,10 +14,22 @@
 {
     using namespace std::string_literals;
     switch (value->type()) {
+    case SR_INT8_T:
+        return value->data()->get_int8();
+    case SR_UINT8_T:
+        return value->data()->get_uint8();
+    case SR_INT16_T:
+        return value->data()->get_int16();
+    case SR_UINT16_T:
+        return value->data()->get_uint16();
     case SR_INT32_T:
         return value->data()->get_int32();
     case SR_UINT32_T:
         return value->data()->get_uint32();
+    case SR_INT64_T:
+        return value->data()->get_int64();
+    case SR_UINT64_T:
+        return value->data()->get_uint64();
     case SR_BOOL_T:
         return value->data()->get_bool();
     case SR_STRING_T:
diff --git a/src/utils.cpp b/src/utils.cpp
index 6555ac6..b6df7e8 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -42,10 +42,22 @@
         return "a decimal";
     case yang::LeafDataTypes::Bool:
         return "a boolean";
-    case yang::LeafDataTypes::Int:
-        return "an integer";
-    case yang::LeafDataTypes::Uint:
-        return "an unsigned integer";
+    case yang::LeafDataTypes::Int8:
+        return "an 8-bit integer";
+    case yang::LeafDataTypes::Uint8:
+        return "an 8-bit unsigned integer";
+    case yang::LeafDataTypes::Int16:
+        return "a 16-bit integer";
+    case yang::LeafDataTypes::Uint16:
+        return "a 16-bit unsigned integer";
+    case yang::LeafDataTypes::Int32:
+        return "a 32-bit integer";
+    case yang::LeafDataTypes::Uint32:
+        return "a 32-bit unsigned integer";
+    case yang::LeafDataTypes::Int64:
+        return "a 64-bit integer";
+    case yang::LeafDataTypes::Uint64:
+        return "a 64-bit unsigned integer";
     case yang::LeafDataTypes::Enum:
         return "an enum";
     case yang::LeafDataTypes::IdentityRef:
diff --git a/src/yang_schema.cpp b/src/yang_schema.cpp
index ca9e4ff..6cd7024 100644
--- a/src/yang_schema.cpp
+++ b/src/yang_schema.cpp
@@ -246,10 +246,22 @@
         return yang::LeafDataTypes::Decimal;
     case LY_TYPE_BOOL:
         return yang::LeafDataTypes::Bool;
+    case LY_TYPE_INT8:
+        return yang::LeafDataTypes::Int8;
+    case LY_TYPE_INT16:
+        return yang::LeafDataTypes::Int16;
     case LY_TYPE_INT32:
-        return yang::LeafDataTypes::Int;
+        return yang::LeafDataTypes::Int32;
+    case LY_TYPE_INT64:
+        return yang::LeafDataTypes::Int64;
+    case LY_TYPE_UINT8:
+        return yang::LeafDataTypes::Uint8;
+    case LY_TYPE_UINT16:
+        return yang::LeafDataTypes::Uint16;
     case LY_TYPE_UINT32:
-        return yang::LeafDataTypes::Uint;
+        return yang::LeafDataTypes::Uint32;
+    case LY_TYPE_UINT64:
+        return yang::LeafDataTypes::Uint64;
     case LY_TYPE_ENUM:
         return yang::LeafDataTypes::Enum;
     case LY_TYPE_BINARY:
diff --git a/tests/leaf_editing.cpp b/tests/leaf_editing.cpp
index 2db8193..1ec4be4 100644
--- a/tests/leaf_editing.cpp
+++ b/tests/leaf_editing.cpp
@@ -26,8 +26,14 @@
     schema->addLeaf("", "mod:leafString", yang::LeafDataTypes::String);
     schema->addLeaf("", "mod:leafDecimal", yang::LeafDataTypes::Decimal);
     schema->addLeaf("", "mod:leafBool", yang::LeafDataTypes::Bool);
-    schema->addLeaf("", "mod:leafInt", yang::LeafDataTypes::Int);
-    schema->addLeaf("", "mod:leafUint", yang::LeafDataTypes::Uint);
+    schema->addLeaf("", "mod:leafInt8", yang::LeafDataTypes::Int8);
+    schema->addLeaf("", "mod:leafInt16", yang::LeafDataTypes::Int16);
+    schema->addLeaf("", "mod:leafInt32", yang::LeafDataTypes::Int32);
+    schema->addLeaf("", "mod:leafInt64", yang::LeafDataTypes::Int64);
+    schema->addLeaf("", "mod:leafUint8", yang::LeafDataTypes::Uint8);
+    schema->addLeaf("", "mod:leafUint16", yang::LeafDataTypes::Uint16);
+    schema->addLeaf("", "mod:leafUint32", yang::LeafDataTypes::Uint32);
+    schema->addLeaf("", "mod:leafUint64", yang::LeafDataTypes::Uint64);
     schema->addLeaf("", "mod:leafBinary", yang::LeafDataTypes::Binary);
     schema->addIdentity(std::nullopt, ModuleValuePair{"mod", "food"});
     schema->addIdentity(std::nullopt, ModuleValuePair{"mod", "vehicle"});
@@ -83,11 +89,67 @@
                 expected.m_data = std::string("somedata");
             }
 
-            SECTION("int")
+            SECTION("int8")
             {
-                input = "set mod:leafInt 2";
-                expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafInt")});
-                expected.m_data = 2;
+                input = "set mod:leafInt8 2";
+                expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafInt8")});
+                expected.m_data = int8_t{2};
+            }
+
+            SECTION("negative int8")
+            {
+                input = "set mod:leafInt8 -10";
+                expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafInt8")});
+                expected.m_data = int8_t{-10};
+            }
+
+            SECTION("uint8")
+            {
+                input = "set mod:leafUint8 2";
+                expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafUint8")});
+                expected.m_data = uint8_t{2};
+            }
+
+            SECTION("int16")
+            {
+                input = "set mod:leafInt16 30000";
+                expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafInt16")});
+                expected.m_data = int16_t{30'000};
+            }
+
+            SECTION("uint16")
+            {
+                input = "set mod:leafUint16 30000";
+                expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafUint16")});
+                expected.m_data = uint16_t{30'000};
+            }
+
+            SECTION("int32")
+            {
+                input = "set mod:leafInt32 30000";
+                expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafInt32")});
+                expected.m_data = int32_t{30'000};
+            }
+
+            SECTION("uint32")
+            {
+                input = "set mod:leafUint32 30000";
+                expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafUint32")});
+                expected.m_data = uint32_t{30'000};
+            }
+
+            SECTION("int32")
+            {
+                input = "set mod:leafInt32 30000";
+                expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafInt32")});
+                expected.m_data = int32_t{30'000};
+            }
+
+            SECTION("uint64")
+            {
+                input = "set mod:leafUint64 30000";
+                expected.m_path.m_nodes.push_back(dataNode_{module_{"mod"}, leaf_("leafUint64")});
+                expected.m_data = uint64_t{30'000};
             }
 
             SECTION("decimal")
@@ -252,13 +314,45 @@
             {
                 input = "set leafBool blabla";
             }
-            SECTION("set leafUint blabla")
+            SECTION("set leafUint8 blabla")
             {
-                input = "set leafUint blabla";
+                input = "set leafUint8 blabla";
             }
-            SECTION("set leafInt blabla")
+            SECTION("set leafUint8 -5")
             {
-                input = "set leafInt blabla";
+                input = "set leafUint8 -5";
+            }
+            SECTION("set leafInt8 blabla")
+            {
+                input = "set leafInt8 blabla";
+            }
+            SECTION("set leafInt8 130")
+            {
+                input = "set leafInt8 130";
+            }
+            SECTION("set leafUint16 blabla")
+            {
+                input = "set leafUint16 blabla";
+            }
+            SECTION("set leafInt16 blabla")
+            {
+                input = "set leafInt16 blabla";
+            }
+            SECTION("set leafUint32 blabla")
+            {
+                input = "set leafUint32 blabla";
+            }
+            SECTION("set leafInt32 blabla")
+            {
+                input = "set leafInt32 blabla";
+            }
+            SECTION("set leafUint64 blabla")
+            {
+                input = "set leafUint64 blabla";
+            }
+            SECTION("set leafInt64 blabla")
+            {
+                input = "set leafInt64 blabla";
             }
             SECTION("set leafEnum blabla")
             {
diff --git a/tests/yang.cpp b/tests/yang.cpp
index 6793250..9c44008 100644
--- a/tests/yang.cpp
+++ b/tests/yang.cpp
@@ -96,14 +96,38 @@
         type boolean;
     }
 
-    leaf leafInt {
+    leaf leafInt8 {
+        type int8;
+    }
+
+    leaf leafUint8 {
+        type uint8;
+    }
+
+    leaf leafInt16 {
+        type int16;
+    }
+
+    leaf leafUint16 {
+        type uint16;
+    }
+
+    leaf leafInt32 {
         type int32;
     }
 
-    leaf leafUint {
+    leaf leafUint32 {
         type uint32;
     }
 
+    leaf leafInt64 {
+        type int64;
+    }
+
+    leaf leafUint64 {
+        type uint64;
+    }
+
     leaf leafEnum {
         type enumeration {
             enum lol;
@@ -543,18 +567,60 @@
                 type = yang::LeafDataTypes::Bool;
             }
 
-            SECTION("leafInt")
+            SECTION("leafInt8")
             {
                 node.first = "example-schema";
-                node.second = "leafInt";
-                type = yang::LeafDataTypes::Int;
+                node.second = "leafInt8";
+                type = yang::LeafDataTypes::Int8;
             }
 
-            SECTION("leafUint")
+            SECTION("leafUint8")
             {
                 node.first = "example-schema";
-                node.second = "leafUint";
-                type = yang::LeafDataTypes::Uint;
+                node.second = "leafUint8";
+                type = yang::LeafDataTypes::Uint8;
+            }
+
+            SECTION("leafInt15")
+            {
+                node.first = "example-schema";
+                node.second = "leafInt16";
+                type = yang::LeafDataTypes::Int16;
+            }
+
+            SECTION("leafUint16")
+            {
+                node.first = "example-schema";
+                node.second = "leafUint16";
+                type = yang::LeafDataTypes::Uint16;
+            }
+
+            SECTION("leafInt32")
+            {
+                node.first = "example-schema";
+                node.second = "leafInt32";
+                type = yang::LeafDataTypes::Int32;
+            }
+
+            SECTION("leafUint32")
+            {
+                node.first = "example-schema";
+                node.second = "leafUint32";
+                type = yang::LeafDataTypes::Uint32;
+            }
+
+            SECTION("leafInt64")
+            {
+                node.first = "example-schema";
+                node.second = "leafInt64";
+                type = yang::LeafDataTypes::Int64;
+            }
+
+            SECTION("leafUint64")
+            {
+                node.first = "example-schema";
+                node.second = "leafUint64";
+                type = yang::LeafDataTypes::Uint64;
             }
 
             SECTION("leafEnum")
@@ -573,8 +639,12 @@
             SECTION("<root>")
             {
                 set = {"example-schema:a", "example-schema:b", "example-schema:leafString",
-                       "example-schema:leafDecimal", "example-schema:leafBool", "example-schema:leafInt",
-                       "example-schema:leafUint", "example-schema:leafEnum", "example-schema:leafEnumTypedef",
+                       "example-schema:leafDecimal", "example-schema:leafBool",
+                       "example-schema:leafInt8", "example-schema:leafUint8",
+                       "example-schema:leafInt16", "example-schema:leafUint16",
+                       "example-schema:leafInt32", "example-schema:leafUint32",
+                       "example-schema:leafInt64", "example-schema:leafUint64",
+                       "example-schema:leafEnum", "example-schema:leafEnumTypedef",
                        "example-schema:leafEnumTypedefRestricted", "example-schema:leafEnumTypedefRestricted2",
                        "example-schema:foodIdentLeaf", "example-schema:pizzaIdentLeaf", "example-schema:foodDrinkIdentLeaf",
                        "example-schema:_list", "example-schema:twoKeyList", "second-schema:bla",