Add support for vtable flags for methods

This adds support for specifying the vtable flags
SD_BUS_VTABLE_DEPRECATED, SD_BUS_VTABLE_HIDDEN,
SD_BUS_VTABLE_UNPRIVILEGED and SD_BUS_VTABLE_METHOD_NO_REPLY for
methods. The list of flags in the YAML file will be ORed together.

Change-Id: I7762ffb15a1483760f3b7e0ea02e80fd52ebd9b9
Signed-off-by: Waqar Hameed <waqarh@axis.com>
diff --git a/docs/interface.md b/docs/interface.md
index f813e31..ff63c34 100644
--- a/docs/interface.md
+++ b/docs/interface.md
@@ -112,16 +112,22 @@
 ## Methods
 
 A method must have the YAML property `name` and may optionally have
-`parameters`, `returns`, `errors`, and `description`.  Each parameter must
-have a `name`, `type`, and optional `description`.  Each return must have a
-`type` and may optionally have a `name` and `description`.  Errors are a list
-of fully-qualified or shortened `self.` identifiers for errors the method may
+`parameters`, `returns`, `flags`, `errors`, and `description`. Each parameter
+must have a `name`, `type`, and optional `description`. Each return must have a
+`type` and may optionally have a `name` and `description`. Flags are a list of
+sd-bus vtable flags; the supported values are `deprecated`, `hidden`,
+`unprivileged`and `no_reply`, which corresponds to `SD_BUS_VTABLE_DEPRECATED`,
+`SD_BUS_VTABLE_HIDDEN`, `SD_BUS_VTABLE_UNPRIVILEGED`,
+`SD_BUS_VTABLE_METHOD_NO_REPLY`, respectively. Errors are a list of
+fully-qualified or shortened `self.` identifiers for errors the method may
 return, which must be defined in a corresponding errors YAML file.
 
 Example:
 ```
 methods:
     - name: Shuffle
+      flags:
+        - unprivileged
       errors:
         - self.Error.TooTired
     - name: Deal
@@ -134,6 +140,9 @@
         - name: Card
           type: struct[enum[self.Suit], byte]
     - name: MoveToTop
+      flags:
+        - deprecated
+        - no_reply
       parameters:
         - name: Card
           type: struct[enum[self.Suit], byte]
diff --git a/example/net/poettering/Calculator.interface.yaml b/example/net/poettering/Calculator.interface.yaml
index 6e44093..a942f5c 100644
--- a/example/net/poettering/Calculator.interface.yaml
+++ b/example/net/poettering/Calculator.interface.yaml
@@ -42,6 +42,9 @@
       errors:
         - self.Error.DivisionByZero
     - name: Clear
+      flags:
+        - unprivileged
+        - no_reply
       description: >
         Reset the LastResult property to zero.
 properties:
diff --git a/sdbusplus/vtable.hpp b/sdbusplus/vtable.hpp
index c2d8ba6..3a0bdb7 100644
--- a/sdbusplus/vtable.hpp
+++ b/sdbusplus/vtable.hpp
@@ -98,6 +98,13 @@
                               sd_bus_property_set_t set, size_t offset,
                               decltype(vtable_t::flags) flags = 0);
 
+namespace common_
+{
+constexpr auto deprecated = SD_BUS_VTABLE_DEPRECATED;
+constexpr auto hidden = SD_BUS_VTABLE_HIDDEN;
+constexpr auto unprivileged = SD_BUS_VTABLE_UNPRIVILEGED;
+} // namespace common_
+
 namespace method_
 {
 constexpr auto no_reply = SD_BUS_VTABLE_METHOD_NO_REPLY;
diff --git a/tools/sdbusplus/method.py b/tools/sdbusplus/method.py
index 8fa09b3..15f8e4f 100644
--- a/tools/sdbusplus/method.py
+++ b/tools/sdbusplus/method.py
@@ -9,6 +9,8 @@
             [Property(**p) for p in kwargs.pop('parameters', [])]
         self.returns = \
             [Property(**r) for r in kwargs.pop('returns', [])]
+        self.flags = kwargs.pop('flags', [])
+        self.cpp_flags = self.or_cpp_flags(self.flags)
         self.errors = kwargs.pop('errors', [])
 
         super(Method, self).__init__(**kwargs)
@@ -19,3 +21,19 @@
     def cpp_prototype(self, loader, interface, ptype):
         return self.render(loader, "method.prototype.hpp.mako", method=self,
                            interface=interface, ptype=ptype, post=str.rstrip)
+
+    def or_cpp_flags(self, flags):
+        """Return the corresponding ORed cpp flags."""
+        flags_dict = {"deprecated": "vtable::common_::deprecated",
+                      "hidden": "vtable::common_::hidden",
+                      "unprivileged": "vtable::common_::unprivileged",
+                      "no_reply": "vtable::method_::no_reply"}
+
+        cpp_flags = []
+        for flag in flags:
+            try:
+                cpp_flags.append(flags_dict[flag])
+            except KeyError:
+                raise ValueError("Invalid flag \"{}\"".format(flag))
+
+        return " | ".join(cpp_flags)
diff --git a/tools/sdbusplus/templates/method.prototype.hpp.mako b/tools/sdbusplus/templates/method.prototype.hpp.mako
index 12fbab3..6178f43 100644
--- a/tools/sdbusplus/templates/method.prototype.hpp.mako
+++ b/tools/sdbusplus/templates/method.prototype.hpp.mako
@@ -101,7 +101,12 @@
                         .data(),
                    details::${interface_name()}::_return_${ method.CamelCase }
                         .data(),
-                   _callback_${ method.CamelCase }),
+        % if method.cpp_flags:
+                   _callback_${method.CamelCase},
+                   ${method.cpp_flags}),
+        % else:
+                   _callback_${method.CamelCase}),
+        % endif
 ###
 ### Emit 'callback-cpp'
 ###