buffet: Add parsing of command instances from JSON

CommandInstance class can be created from a JSON object
with proper command and parameter value validation against
command definition schema.

BUG=chromium:396713
TEST=USE=buffet P2_TEST_FILTER="buffet::*" FEATURES=test emerge-link platform2

Change-Id: Iba4c807225552f6a9d8b33a0aa1fc451e75753a4
Reviewed-on: https://chromium-review.googlesource.com/211338
Reviewed-by: Christopher Wiley <wiley@chromium.org>
Commit-Queue: Alex Vakulenko <avakulenko@chromium.org>
Tested-by: Alex Vakulenko <avakulenko@chromium.org>
diff --git a/buffet/commands/command_instance.h b/buffet/commands/command_instance.h
index 0028c88..f5d259d 100644
--- a/buffet/commands/command_instance.h
+++ b/buffet/commands/command_instance.h
@@ -13,15 +13,23 @@
 
 #include "buffet/commands/prop_values.h"
 #include "buffet/commands/schema_utils.h"
+#include "buffet/error.h"
+
+namespace base {
+class Value;
+}  // namespace base
 
 namespace buffet {
 
+class CommandDictionary;
+
 class CommandInstance final {
  public:
   // Construct a command instance given the full command |name| which must
   // be in format "<package_name>.<command_name>", a command |category| and
   // a list of parameters and their values specified in |parameters|.
-  CommandInstance(const std::string& name, const std::string& category,
+  CommandInstance(const std::string& name,
+                  const std::string& category,
                   const native_types::Object& parameters);
 
   // Returns the full name of the command.
@@ -34,6 +42,15 @@
   // with given name does not exist, returns null shared_ptr.
   std::shared_ptr<const PropValue> FindParameter(const std::string& name) const;
 
+  // Parses a command instance JSON definition and constructs a CommandInstance
+  // object, checking the JSON |value| against the command definition schema
+  // found in command |dictionary|. On error, returns null unique_ptr and
+  // fills in error details in |error|.
+  static std::unique_ptr<const CommandInstance> FromJson(
+      const base::Value* value,
+      const CommandDictionary& dictionary,
+      ErrorPtr* error);
+
  private:
   // Full command name as "<package_name>.<command_name>".
   std::string name_;