[fidlc] Expose max_out_of_line in the JSON IR.

Straight-forward change which emits the maximum secondary storage
payload size where applicable. This can be used to implement smarter
allocation strategies e.g. make the buffer exactly as big as the
message.

This will also be used by the low-level C++ binding to implement the
FidlType::MaxSize trait.

FIDL-305 #comment

TEST: make -j36 && build-x64/host_tests/fidl-compiler-test

Change-Id: Ib7b7ed1943c7093749eddc2add17afca5966c5aa
diff --git a/system/host/fidl/lib/json_generator.cpp b/system/host/fidl/lib/json_generator.cpp
index da14dca..124d424 100644
--- a/system/host/fidl/lib/json_generator.cpp
+++ b/system/host/fidl/lib/json_generator.cpp
@@ -443,6 +443,7 @@
             GenerateObjectMember("maybe_attributes", value.attributes);
         GenerateObjectMember("members", value.members);
         GenerateObjectMember("size", value.typeshape.Size());
+        GenerateObjectMember("max_out_of_line", value.typeshape.MaxOutOfLine());
         GenerateObjectMember("alignment", value.typeshape.Alignment());
         GenerateObjectMember("max_handles", value.typeshape.MaxHandles());
     });
@@ -457,6 +458,7 @@
         if (value.maybe_default_value)
             GenerateObjectMember("maybe_default_value", value.maybe_default_value);
         GenerateObjectMember("size", value.fieldshape.Size());
+        GenerateObjectMember("max_out_of_line", value.fieldshape.MaxOutOfLine());
         GenerateObjectMember("alignment", value.fieldshape.Alignment());
         GenerateObjectMember("offset", value.fieldshape.Offset());
         GenerateObjectMember("max_handles", value.fieldshape.MaxHandles());
@@ -470,6 +472,7 @@
             GenerateObjectMember("maybe_attributes", value.attributes);
         GenerateObjectMember("members", value.members);
         GenerateObjectMember("size", value.typeshape.Size());
+        GenerateObjectMember("max_out_of_line", value.typeshape.MaxOutOfLine());
         GenerateObjectMember("alignment", value.typeshape.Alignment());
         GenerateObjectMember("max_handles", value.typeshape.MaxHandles());
     });
@@ -487,6 +490,7 @@
             if (value.maybe_used->maybe_default_value)
                 GenerateObjectMember("maybe_default_value", value.maybe_used->maybe_default_value);
             GenerateObjectMember("size", value.maybe_used->typeshape.Size());
+            GenerateObjectMember("max_out_of_line", value.maybe_used->typeshape.MaxOutOfLine());
             GenerateObjectMember("alignment", value.maybe_used->typeshape.Alignment());
             GenerateObjectMember("max_handles", value.maybe_used->typeshape.MaxHandles());
         } else {
@@ -502,6 +506,7 @@
             GenerateObjectMember("maybe_attributes", value.attributes);
         GenerateObjectMember("members", value.members);
         GenerateObjectMember("size", value.typeshape.Size());
+        GenerateObjectMember("max_out_of_line", value.typeshape.MaxOutOfLine());
         GenerateObjectMember("alignment", value.typeshape.Alignment());
         GenerateObjectMember("max_handles", value.typeshape.MaxHandles());
     });
@@ -514,6 +519,7 @@
         if (value.attributes)
             GenerateObjectMember("maybe_attributes", value.attributes);
         GenerateObjectMember("size", value.fieldshape.Size());
+        GenerateObjectMember("max_out_of_line", value.fieldshape.MaxOutOfLine());
         GenerateObjectMember("alignment", value.fieldshape.Alignment());
         GenerateObjectMember("offset", value.fieldshape.Offset());
     });
diff --git a/system/host/fidl/schema.json b/system/host/fidl/schema.json
index 8c71af8..3e2e073 100644
--- a/system/host/fidl/schema.json
+++ b/system/host/fidl/schema.json
@@ -259,6 +259,7 @@
                 "type",
                 "name",
                 "size",
+                "max_out_of_line",
                 "alignment",
                 "offset"
             ],
@@ -275,6 +276,10 @@
                     "description": "Size of the parameter or return",
                     "$ref": "#/definitions/count"
                 },
+                "max_out_of_line": {
+                    "description": "Maximum size of the out-of-line payload",
+                    "$ref": "#/definitions/count"
+                },
                 "alignment": {
                     "description": "Alignment of the parameter or return",
                     "$ref": "#/definitions/count"
@@ -291,7 +296,8 @@
             "required": [
                 "name",
                 "members",
-                "size"
+                "size",
+                "max_out_of_line"
             ],
             "properties": {
                 "max_handles": {
@@ -320,6 +326,10 @@
                 "size": {
                     "description": "Size of struct",
                     "$ref": "#/definitions/count"
+                },
+                "max_out_of_line": {
+                    "description": "Maximum size of the out-of-line struct payload",
+                    "$ref": "#/definitions/count"
                 }
             }
         },
@@ -330,6 +340,7 @@
                 "type",
                 "name",
                 "size",
+                "max_out_of_line",
                 "alignment",
                 "offset"
             ],
@@ -346,6 +357,10 @@
                     "description": "Size of struct member",
                     "$ref": "#/definitions/count"
                 },
+                "max_out_of_line": {
+                    "description": "Maximum size of the out-of-line payload",
+                    "$ref": "#/definitions/count"
+                },
                 "alignment": {
                     "description": "Alignment of the struct member",
                     "$ref": "#/definitions/count"
@@ -370,7 +385,8 @@
             "required": [
                 "name",
                 "members",
-                "size"
+                "size",
+                "max_out_of_line"
             ],
             "properties": {
                 "max_handles": {
@@ -395,6 +411,10 @@
                 "size": {
                     "description": "Size of table",
                     "$ref": "#/definitions/count"
+                },
+                "max_out_of_line": {
+                    "description": "Maximum size of the out-of-line payload for the entire table. Note that this value is computed without considering future member additions, otherwise it would always be pegged at the maximum. Bindings should take this into consideration when using max_out_of_line.",
+                    "$ref": "#/definitions/count"
                 }
             }
         },
@@ -426,6 +446,10 @@
                     "description": "Size of table member",
                     "$ref": "#/definitions/count"
                 },
+                "max_out_of_line": {
+                    "description": "Maximum size of the out-of-line payload",
+                    "$ref": "#/definitions/count"
+                },
                 "alignment": {
                     "description": "Alignment of table member",
                     "$ref": "#/definitions/count"
@@ -447,6 +471,7 @@
                 "name",
                 "members",
                 "size",
+                "max_out_of_line",
                 "alignment"
             ],
             "properties": {
@@ -473,6 +498,10 @@
                     "description": "Size of union",
                     "$ref": "#/definitions/count"
                 },
+                "max_out_of_line": {
+                    "description": "Maximum size of the out-of-line payload",
+                    "$ref": "#/definitions/count"
+                },
                 "alignment": {
                     "description": "Alignment of union",
                     "$ref": "#/definitions/count"
@@ -486,6 +515,7 @@
                 "type",
                 "name",
                 "size",
+                "max_out_of_line",
                 "alignment",
                 "offset"
             ],
@@ -502,6 +532,10 @@
                     "description": "Size of union member",
                     "$ref": "#/definitions/count"
                 },
+                "max_out_of_line": {
+                    "description": "Maximum size of the out-of-line payload",
+                    "$ref": "#/definitions/count"
+                },
                 "alignment": {
                     "description": "Alignment of union member",
                     "$ref": "#/definitions/count"
diff --git a/system/utest/fidl-compiler/json_generator_tests.cpp b/system/utest/fidl-compiler/json_generator_tests.cpp
index 56289b2..6c21c26 100644
--- a/system/utest/fidl-compiler/json_generator_tests.cpp
+++ b/system/utest/fidl-compiler/json_generator_tests.cpp
@@ -93,6 +93,7 @@
           },
           "name": "f1",
           "size": 1,
+          "max_out_of_line": 0,
           "alignment": 1,
           "offset": 0,
           "max_handles": 0
@@ -104,12 +105,14 @@
           },
           "name": "f2",
           "size": 1,
+          "max_out_of_line": 0,
           "alignment": 1,
           "offset": 1,
           "max_handles": 0
         }
       ],
       "size": 2,
+      "max_out_of_line": 0,
       "alignment": 1,
       "max_handles": 0
     }
@@ -169,6 +172,7 @@
               },
               "name": "e",
               "size": 1,
+              "max_out_of_line": 0,
               "alignment": 1,
               "offset": 16,
               "max_handles": 0
@@ -192,6 +196,7 @@
               },
               "name": "e",
               "size": 1,
+              "max_out_of_line": 0,
               "alignment": 1,
               "offset": 16,
               "max_handles": 0
@@ -213,6 +218,7 @@
               },
               "name": "e",
               "size": 1,
+              "max_out_of_line": 0,
               "alignment": 1,
               "offset": 16,
               "max_handles": 0
@@ -230,6 +236,7 @@
               },
               "name": "e",
               "size": 1,
+              "max_out_of_line": 0,
               "alignment": 1,
               "offset": 16,
               "max_handles": 0
@@ -247,6 +254,7 @@
       "anonymous": false,
       "members": [],
       "size": 1,
+      "max_out_of_line": 0,
       "alignment": 1,
       "max_handles": 0
     }
@@ -304,6 +312,7 @@
           },
           "name": "f1",
           "size": 1,
+          "max_out_of_line": 0,
           "alignment": 1,
           "max_handles": 0
         },
@@ -316,6 +325,7 @@
           },
           "name": "f2",
           "size": 1,
+          "max_out_of_line": 0,
           "alignment": 1,
           "max_handles": 0
         },
@@ -325,6 +335,7 @@
         }
       ],
       "size": 16,
+      "max_out_of_line": 48,
       "alignment": 8,
       "max_handles": 0
     }
@@ -389,12 +400,14 @@
           },
           "name": "toppings",
           "size": 16,
+          "max_out_of_line": 4294967295,
           "alignment": 8,
           "offset": 0,
           "max_handles": 0
         }
       ],
       "size": 16,
+      "max_out_of_line": 4294967295,
       "alignment": 8,
       "max_handles": 0
     },
@@ -410,12 +423,14 @@
           },
           "name": "sauce",
           "size": 16,
+          "max_out_of_line": 16,
           "alignment": 8,
           "offset": 0,
           "max_handles": 0
         }
       ],
       "size": 16,
+      "max_out_of_line": 16,
       "alignment": 8,
       "max_handles": 0
     }
@@ -433,6 +448,7 @@
           },
           "name": "pizza",
           "size": 16,
+          "max_out_of_line": 4294967295,
           "alignment": 8,
           "offset": 8
         },
@@ -444,11 +460,13 @@
           },
           "name": "pasta",
           "size": 16,
+          "max_out_of_line": 16,
           "alignment": 8,
           "offset": 8
         }
       ],
       "size": 24,
+      "max_out_of_line": 4294967295,
       "alignment": 8,
       "max_handles": 0
     }
@@ -516,6 +534,7 @@
               },
               "name": "s",
               "size": 16,
+              "max_out_of_line": 4294967295,
               "alignment": 8,
               "offset": 16,
               "max_handles": 0
@@ -532,6 +551,7 @@
               },
               "name": "y",
               "size": 8,
+              "max_out_of_line": 0,
               "alignment": 8,
               "offset": 16,
               "max_handles": 0
@@ -557,6 +577,7 @@
               },
               "name": "s",
               "size": 16,
+              "max_out_of_line": 4294967295,
               "alignment": 8,
               "offset": 16,
               "max_handles": 0
@@ -573,6 +594,7 @@
               },
               "name": "y",
               "size": 8,
+              "max_out_of_line": 0,
               "alignment": 8,
               "offset": 16,
               "max_handles": 0