Add a chain style to formatter.

It is now valid to do, for example:
out.sIf("condition", [&] {
    out << "statement1;" << "\n"
        << "statement2;" << "\n";
}).endl();

Test: compiles
Test: hidl_test
Change-Id: Iab104644a005ac8386813a0f249a87ebd0284837
diff --git a/generateCpp.cpp b/generateCpp.cpp
index 0ef61e1..ec79059 100644
--- a/generateCpp.cpp
+++ b/generateCpp.cpp
@@ -840,16 +840,12 @@
 
 // static
 void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
-    out << "if (" << nonNull << " == nullptr) {\n";
-    out.indent();
-    out << "return ::android::hardware::Status::fromExceptionCode(\n";
-    out.indent();
-    out.indent();
-    out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
-    out.unindent();
-    out.unindent();
-    out.unindent();
-    out << "}\n\n";
+    out.sIf(nonNull + " == nullptr", [&] {
+        out << "return ::android::hardware::Status::fromExceptionCode(\n";
+        out.indent(2, [&] {
+            out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
+        });
+    }).endl().endl();
 }
 
 status_t AST::generateTypeSource(
@@ -1229,18 +1225,13 @@
     out.unindent();
     out << "}\n\n";
 
-    out << "if (_hidl_err == ::android::UNEXPECTED_NULL) {\n";
-    out.indent();
-    out << "_hidl_err = ::android::hardware::writeToParcel(\n";
-    out.indent();
-    out.indent();
-    out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
-    out << "_hidl_reply);\n";
-    out.unindent();
-    out.unindent();
-
-    out.unindent();
-    out << "}\n\n";
+    out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
+        out << "_hidl_err = ::android::hardware::writeToParcel(\n";
+        out.indent(2, [&] {
+            out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
+            out << "_hidl_reply);\n";
+        });
+    });
 
     out << "return _hidl_err;\n";
 
diff --git a/utils/Formatter.cpp b/utils/Formatter.cpp
index 404c0c6..6709785 100644
--- a/utils/Formatter.cpp
+++ b/utils/Formatter.cpp
@@ -42,14 +42,21 @@
     mIndentDepth -= level;
 }
 
-void Formatter::indent(size_t level, std::function<void(void)> func) {
+Formatter &Formatter::indent(size_t level, std::function<void(void)> func) {
     this->indent(level);
     func();
     this->unindent(level);
+    return *this;
 }
 
-void Formatter::indent(std::function<void(void)> func) {
-    this->indent(1, func);
+Formatter &Formatter::indent(std::function<void(void)> func) {
+    return this->indent(1, func);
+}
+
+Formatter &Formatter::block(std::function<void(void)> func) {
+    (*this) << "{\n";
+    this->indent(func);
+    return (*this) << "}";
 }
 
 void Formatter::setLinePrefix(const std::string &prefix) {
@@ -60,6 +67,26 @@
     mLinePrefix = "";
 }
 
+Formatter &Formatter::endl() {
+    return (*this) << "\n";
+}
+
+Formatter &Formatter::sIf(const std::string &cond, std::function<void(void)> block) {
+    (*this) << "if (" << cond << ") ";
+    return this->block(block);
+}
+
+Formatter &Formatter::sElseIf(const std::string &cond, std::function<void(void)> block) {
+    (*this) << " else if (" << cond << ") ";
+    return this->block(block);
+}
+
+Formatter &Formatter::sElse(std::function<void(void)> block) {
+    (*this) << " else ";
+    return this->block(block);
+}
+
+
 Formatter &Formatter::operator<<(const std::string &out) {
     const size_t len = out.length();
     size_t start = 0;
diff --git a/utils/include/hidl-util/Formatter.h b/utils/include/hidl-util/Formatter.h
index 6264159..7a27287 100644
--- a/utils/include/hidl-util/Formatter.h
+++ b/utils/include/hidl-util/Formatter.h
@@ -24,7 +24,13 @@
 
 namespace android {
 
+// Two styles to use a Formatter.
+// One is with .indent() calls and operator<<.
+//     out << "if (good) {\n"; out.indent(); out << "blah\nblah\n"; out.unindent(); out << "}\n";
+// The other is with chain calls and lambda functions
+//     out.sIf("good", [&] { out("blah").endl()("blah").endl(); }).endl();
 struct Formatter {
+
     // Assumes ownership of file. Directed to stdout if file == NULL.
     Formatter(FILE *file = NULL);
     ~Formatter();
@@ -32,14 +38,46 @@
     void indent(size_t level = 1);
     void unindent(size_t level = 1);
 
+    // Note that The last \n after the last line is NOT added automatically.
     // out.indent(2, [&] {
     //     out << "Meow\n";
     // });
-    void indent(size_t level, std::function<void(void)> func);
+    Formatter &indent(size_t level, std::function<void(void)> func);
+
+    // Note that The last \n after the last line is NOT added automatically.
     // out.indent([&] {
     //     out << "Meow\n";
     // });
-    void indent(std::function<void(void)> func);
+    Formatter &indent(std::function<void(void)> func);
+
+    // A block inside braces.
+    // * No space will be added before the opening brace.
+    // * The last \n before the closing brace is added automatically.
+    // * There will NOT be a \n after the closing brace.
+    // out.block([&] {
+    //     out << "one();\n"
+    //         << "two();\n";
+    // });
+    // is equivalent to
+    // out << "{\n"
+    //     << "one();\ntwo();\n" // func()
+    //     << "}";
+    Formatter &block(std::function<void(void)> func);
+
+    // A synonym to (*this) << "\n";
+    Formatter &endl();
+
+    // out.sIf("z == 1", [&] {
+    //     out << "doGoodStuff();\n";
+    // }).sElseIf("z == 2", [&] {
+    //     out << "doBadStuff();\n";
+    // }).sElse([&] {
+    //     out << "logFatal();\n";
+    // }).endl();
+    // note that there will be a space before the "else"-s.
+    Formatter &sIf(const std::string &cond, std::function<void(void)> block);
+    Formatter &sElseIf(const std::string &cond, std::function<void(void)> block);
+    Formatter &sElse(std::function<void(void)> block);
 
     Formatter &operator<<(const std::string &out);
     Formatter &operator<<(size_t n);