[fidlc] Cleaning up tests

- TestLibrary now supports multiple sources per-library
- TestLibrary is now final, and all tests which used special
subclasses are now simply using the API
- Merging max_bytes_tests.cpp, max_bytes_multipass_tests.cpp, and
max_bytes_tests.cpp into a single typeshape_tests.cpp
- Improving coverage by checking typeshapes consistently, and always
verifying size, alignement, max-out-of-line, max-handles, and depth
- Moved optionals_tests.cpp into type_alias_tests.cpp
- Minor test renames (removing test_ prefix)

FIDL-458 #done

Change-Id: I2fc3d4dae7cb212a0228909f5aae2d7524093b58
diff --git a/zircon/system/utest/fidl-compiler/BUILD.gn b/zircon/system/utest/fidl-compiler/BUILD.gn
index 2620932..2c5fb77 100644
--- a/zircon/system/utest/fidl-compiler/BUILD.gn
+++ b/zircon/system/utest/fidl-compiler/BUILD.gn
@@ -58,18 +58,15 @@
       "flat_ast_tests.cpp",
       "formatter_tests.cpp",
       "json_generator_tests.cpp",
-      "lint_tests.cpp",
       "lint_findings_tests.cpp",
-      "max_bytes_multipass_tests.cpp",
-      "max_bytes_tests.cpp",
-      "max_handle_tests.cpp",
-      "optionals_tests.cpp",
+      "lint_tests.cpp",
       "ordinals_tests.cpp",
       "parsing_tests.cpp",
       "protocol_tests.cpp",
       "table_tests.cpp",
       "type_alias_tests.cpp",
       "types_tests.cpp",
+      "typeshape_tests.cpp",
       "using_tests.cpp",
       "virtual_source_tests.cpp",
       "visitor_unittests.cpp",
diff --git a/zircon/system/utest/fidl-compiler/attributes_tests.cpp b/zircon/system/utest/fidl-compiler/attributes_tests.cpp
index 798bb31..0d9512a9 100644
--- a/zircon/system/utest/fidl-compiler/attributes_tests.cpp
+++ b/zircon/system/utest/fidl-compiler/attributes_tests.cpp
@@ -60,18 +60,18 @@
 bool no_two_same_attribute_on_library_test() {
     BEGIN_TEST;
 
-    TestLibrary library("dup_attributes.fidl", R"FIDL(
+    TestLibrary library;
+    library.AddSource("dup_attributes.fidl", R"FIDL(
 [dup = "first"]
 library fidl.test.dupattributes;
 
 )FIDL");
-    EXPECT_TRUE(library.Compile());
-
-    EXPECT_FALSE(library.AddSourceFile("dup_attributes_second.fidl", R"FIDL(
+    library.AddSource("dup_attributes_second.fidl", R"FIDL(
 [dup = "second"]
 library fidl.test.dupattributes;
 
-)FIDL"));
+)FIDL");
+    ASSERT_FALSE(library.Compile());
     auto errors = library.errors();
     ASSERT_EQ(errors.size(), 1);
     ASSERT_STR_STR(errors[0].c_str(), "duplicate attribute with name 'dup'");
diff --git a/zircon/system/utest/fidl-compiler/formatter_tests.cpp b/zircon/system/utest/fidl-compiler/formatter_tests.cpp
index 4700a8c..80aece8 100644
--- a/zircon/system/utest/fidl-compiler/formatter_tests.cpp
+++ b/zircon/system/utest/fidl-compiler/formatter_tests.cpp
@@ -23,7 +23,7 @@
     for (auto element : Examples::map()) {
         TestLibrary library(element.first, element.second);
         std::unique_ptr<fidl::raw::File> ast;
-        library.Parse(ast);
+        library.Parse(&ast);
 
         fidl::raw::FormattingTreeVisitor visitor;
         visitor.OnFile(ast);
@@ -39,7 +39,7 @@
     for (auto element : formatted_output_) {
         TestLibrary library(element.first, element.second);
         std::unique_ptr<fidl::raw::File> ast;
-        EXPECT_TRUE(library.Parse(ast));
+        EXPECT_TRUE(library.Parse(&ast));
 
         fidl::raw::FormattingTreeVisitor visitor;
         visitor.OnFile(ast);
diff --git a/zircon/system/utest/fidl-compiler/lint_findings_tests.cpp b/zircon/system/utest/fidl-compiler/lint_findings_tests.cpp
index ffdc4c8..7672edf 100644
--- a/zircon/system/utest/fidl-compiler/lint_findings_tests.cpp
+++ b/zircon/system/utest/fidl-compiler/lint_findings_tests.cpp
@@ -90,7 +90,7 @@
         ASSERT_STRING_EQ(finding.subcategory(), check_id_, context);
         ASSERT_STRING_EQ(
             finding.source_location().position(),
-            library.FileLocation(source_template_.str(), "${TEST}"), context);
+            FileLocation(source_template_.str(), "${TEST}"), context);
         ASSERT_STRING_EQ(finding.message(), message_, context);
         if (!suggestion_.has_value()) {
             ASSERT_FALSE(finding.suggestion().has_value(), context);
@@ -125,6 +125,23 @@
         return true;
     }
 
+    static std::string FileLocation(const std::string& within, const std::string& to_find) {
+        std::istringstream lines(within);
+        std::string line;
+        size_t line_number = 0;
+        while (std::getline(lines, line)) {
+            line_number++;
+            size_t column_index = line.find(to_find);
+            if (column_index != std::string::npos) {
+                std::stringstream position;
+                position << "example.fidl:" << line_number << ":" << (column_index + 1);
+                return position.str();
+            }
+        }
+        assert(false); // Bug in test
+        return "never reached";
+    }
+
     std::string check_id_;
     std::string message_;
     std::optional<std::string> suggestion_;
diff --git a/zircon/system/utest/fidl-compiler/max_bytes_multipass_tests.cpp b/zircon/system/utest/fidl-compiler/max_bytes_multipass_tests.cpp
deleted file mode 100644
index 4dad7ea..0000000
--- a/zircon/system/utest/fidl-compiler/max_bytes_multipass_tests.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <algorithm>
-#include <unittest/unittest.h>
-
-#include <fidl/flat_ast.h>
-#include <fidl/lexer.h>
-#include <fidl/parser.h>
-#include <fidl/source_file.h>
-
-#include "test_library.h"
-
-namespace {
-
-class MaxBytesMultiPassLibrary : public TestLibrary {
-public:
-    MaxBytesMultiPassLibrary()
-        : TestLibrary(multipass_main_file) {
-        source_files_.push_back(
-            MakeSourceFile("max_bytes_multipass_main.fidl", multipass_main_file));
-        source_files_.push_back(
-            MakeSourceFile("max_bytes_multipass_extern_defs.fidl", multipass_extern_defs_file));
-    }
-
-    MaxBytesMultiPassLibrary(MaxBytesMultiPassLibrary&) = delete;
-    MaxBytesMultiPassLibrary& operator=(MaxBytesMultiPassLibrary&) = delete;
-
-    bool Compile() {
-        for (auto& file : source_files_) {
-            fidl::Lexer lexer(*file, error_reporter_);
-            fidl::Parser parser(&lexer, error_reporter_);
-
-            auto ast = parser.Parse();
-            if (!parser.Ok() || !library_->ConsumeFile(std::move(ast))) {
-                return false;
-            }
-        }
-
-        return library_->Compile();
-    }
-
-    fidl::flat::Library& GetLibrary() const {
-        return *library_;
-    }
-
-private:
-    static constexpr auto multipass_main_file = R"FIDL(
-library fidl.test.maxbytesmultipass;
-
-struct SimpleStruct {
-    uint32 a;
-};
-
-struct OptionalStruct {
-    SimpleStruct? a;
-    SimpleStruct? b;
-};
-
-struct HandleStruct {
-    uint32 a;
-    handle<vmo> b;
-};
-
-struct ArrayOfSimpleStructs {
-    array<SimpleStruct>:42 arr;
-};
-
-struct ArrayOfOptionalStructs {
-    array<OptionalStruct>:42 arr;
-};
-
-struct ArrayOfHandleStructs {
-    array<HandleStruct>:42 arr;
-};
-
-union OptionalAndHandleUnion {
-    OptionalStruct opt;
-    HandleStruct hnd;
-};
-
-struct ArrayOfOptionalAndHandleUnions {
-    array<OptionalAndHandleUnion>:42 arr;
-};
-
-struct ExternalArrayStruct {
-    array<ExternalSimpleStruct>:EXTERNAL_SIZE_DEF a;
-};
-
-struct ExternalStringSizeStruct {
-    string:EXTERNAL_SIZE_DEF a;
-};
-
-struct ExternalVectorSizeStruct {
-    vector<handle>:EXTERNAL_SIZE_DEF a;
-};
-
-)FIDL";
-
-    static constexpr auto multipass_extern_defs_file = R"FIDL(
-library fidl.test.maxbytesmultipass;
-
-const uint32 EXTERNAL_SIZE_DEF = ANOTHER_INDIRECTION;
-const uint32 ANOTHER_INDIRECTION = 32;
-
-struct ExternalSimpleStruct {
-    uint32 a;
-};
-
-)FIDL";
-    std::vector<std::unique_ptr<fidl::SourceFile>> source_files_;
-};
-
-static bool simple_struct_array(void) {
-    BEGIN_TEST;
-
-    MaxBytesMultiPassLibrary test_library;
-    EXPECT_TRUE(test_library.Compile());
-
-    auto smp_struct = test_library.LookupStruct("SimpleStruct");
-    EXPECT_NONNULL(smp_struct);
-    EXPECT_EQ(smp_struct->typeshape.Size(), 4);
-    EXPECT_EQ(smp_struct->typeshape.MaxOutOfLine(), 0);
-    EXPECT_EQ(smp_struct->typeshape.MaxHandles(), 0);
-
-    auto arr_of_smps = test_library.LookupStruct("ArrayOfSimpleStructs");
-    EXPECT_NONNULL(arr_of_smps);
-    EXPECT_EQ(arr_of_smps->typeshape.Size(), smp_struct->typeshape.Size() * 42);
-    EXPECT_EQ(arr_of_smps->typeshape.MaxOutOfLine(), smp_struct->typeshape.MaxOutOfLine() * 42);
-    EXPECT_EQ(arr_of_smps->typeshape.MaxHandles(), smp_struct->typeshape.MaxHandles() * 42);
-
-    END_TEST;
-}
-
-static bool optional_struct_array(void) {
-    BEGIN_TEST;
-
-    MaxBytesMultiPassLibrary test_library;
-    EXPECT_TRUE(test_library.Compile());
-
-    auto opt_struct = test_library.LookupStruct("OptionalStruct");
-    EXPECT_NONNULL(opt_struct);
-    EXPECT_EQ(opt_struct->typeshape.Size(), 16);
-    EXPECT_EQ(opt_struct->typeshape.MaxOutOfLine(), 16);
-    EXPECT_EQ(opt_struct->typeshape.MaxHandles(), 0);
-
-    auto arr_of_opt_struct = test_library.LookupStruct("ArrayOfOptionalStructs");
-    EXPECT_NONNULL(arr_of_opt_struct);
-    EXPECT_EQ(arr_of_opt_struct->typeshape.Size(), opt_struct->typeshape.Size() * 42);
-    EXPECT_EQ(arr_of_opt_struct->typeshape.MaxOutOfLine(),
-              opt_struct->typeshape.MaxOutOfLine() * 42);
-    EXPECT_EQ(arr_of_opt_struct->typeshape.MaxHandles(), opt_struct->typeshape.MaxHandles() * 42);
-
-    END_TEST;
-}
-
-static bool handle_struct_array(void) {
-    BEGIN_TEST;
-
-    MaxBytesMultiPassLibrary test_library;
-    EXPECT_TRUE(test_library.Compile());
-
-    auto hnd_struct = test_library.LookupStruct("HandleStruct");
-    EXPECT_NONNULL(hnd_struct);
-    EXPECT_EQ(hnd_struct->typeshape.Size(), 8);
-    EXPECT_EQ(hnd_struct->typeshape.MaxOutOfLine(), 0);
-    EXPECT_EQ(hnd_struct->typeshape.MaxHandles(), 1);
-
-    auto arr_of_hnd_struct = test_library.LookupStruct("ArrayOfHandleStructs");
-    EXPECT_NONNULL(arr_of_hnd_struct);
-    EXPECT_EQ(arr_of_hnd_struct->typeshape.Size(), hnd_struct->typeshape.Size() * 42);
-    EXPECT_EQ(arr_of_hnd_struct->typeshape.MaxOutOfLine(),
-              hnd_struct->typeshape.MaxOutOfLine() * 42);
-    EXPECT_EQ(arr_of_hnd_struct->typeshape.MaxHandles(), hnd_struct->typeshape.MaxHandles() * 42);
-
-    END_TEST;
-}
-static bool optional_handle_union_array(void) {
-    BEGIN_TEST;
-
-    MaxBytesMultiPassLibrary test_library;
-    EXPECT_TRUE(test_library.Compile());
-
-    auto opt_struct = test_library.LookupStruct("OptionalStruct");
-    EXPECT_NONNULL(opt_struct);
-
-    auto hnd_struct = test_library.LookupStruct("HandleStruct");
-    EXPECT_NONNULL(hnd_struct);
-
-    auto opt_hnd_union = test_library.LookupUnion("OptionalAndHandleUnion");
-    EXPECT_NONNULL(opt_hnd_union);
-    EXPECT_EQ(opt_hnd_union->typeshape.Size(), 24);
-    EXPECT_EQ(opt_hnd_union->typeshape.MaxOutOfLine(),
-              std::max(opt_struct->typeshape.MaxOutOfLine(), hnd_struct->typeshape.MaxOutOfLine()));
-    EXPECT_EQ(opt_hnd_union->typeshape.MaxHandles(),
-              std::max(opt_struct->typeshape.MaxHandles(), hnd_struct->typeshape.MaxHandles()));
-
-    auto arr_of_unions_struct = test_library.LookupStruct("ArrayOfOptionalAndHandleUnions");
-    EXPECT_NONNULL(arr_of_unions_struct);
-    EXPECT_EQ(arr_of_unions_struct->typeshape.Size(), opt_hnd_union->typeshape.Size() * 42);
-    EXPECT_EQ(arr_of_unions_struct->typeshape.MaxOutOfLine(),
-              opt_hnd_union->typeshape.MaxOutOfLine() * 42);
-    EXPECT_EQ(arr_of_unions_struct->typeshape.MaxHandles(),
-              opt_hnd_union->typeshape.MaxHandles() * 42);
-
-    END_TEST;
-}
-
-static bool external_definitions(void) {
-    BEGIN_TEST;
-
-    MaxBytesMultiPassLibrary test_library;
-    EXPECT_TRUE(test_library.Compile());
-
-    auto ext_struct = test_library.LookupStruct("ExternalSimpleStruct");
-    EXPECT_NONNULL(ext_struct);
-    EXPECT_EQ(ext_struct->typeshape.Size(), 4);
-    EXPECT_EQ(ext_struct->typeshape.MaxOutOfLine(), 0);
-    EXPECT_EQ(ext_struct->typeshape.MaxHandles(), 0);
-
-    auto ext_arr_struct = test_library.LookupStruct("ExternalArrayStruct");
-    EXPECT_NONNULL(ext_arr_struct);
-    EXPECT_EQ(ext_arr_struct->typeshape.Size(), ext_struct->typeshape.Size() * 32);
-
-    auto ext_str_struct = test_library.LookupStruct("ExternalStringSizeStruct");
-    EXPECT_NONNULL(ext_str_struct);
-    EXPECT_EQ(ext_str_struct->typeshape.MaxOutOfLine(), 32);
-
-    auto ext_vec_struct = test_library.LookupStruct("ExternalVectorSizeStruct");
-    EXPECT_NONNULL(ext_vec_struct);
-    EXPECT_EQ(ext_vec_struct->typeshape.MaxOutOfLine(), 32 * 4);
-    EXPECT_EQ(ext_vec_struct->typeshape.MaxHandles(), 32);
-
-    END_TEST;
-}
-
-} // namespace
-
-BEGIN_TEST_CASE(max_bytes_multipass_tests)
-RUN_TEST(simple_struct_array)
-RUN_TEST(optional_struct_array)
-RUN_TEST(handle_struct_array)
-RUN_TEST(optional_handle_union_array)
-RUN_TEST(external_definitions)
-END_TEST_CASE(max_bytes_multipass_tests)
diff --git a/zircon/system/utest/fidl-compiler/max_bytes_tests.cpp b/zircon/system/utest/fidl-compiler/max_bytes_tests.cpp
deleted file mode 100644
index eefed3c..0000000
--- a/zircon/system/utest/fidl-compiler/max_bytes_tests.cpp
+++ /dev/null
@@ -1,996 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <unittest/unittest.h>
-
-#include <fidl/flat_ast.h>
-#include <fidl/lexer.h>
-#include <fidl/parser.h>
-#include <fidl/source_file.h>
-
-#include "test_library.h"
-
-// TODO(FIDL-458): Merge with max_handle_tests.
-
-namespace {
-
-class MaxBytesLibrary : public TestLibrary {
-public:
-    MaxBytesLibrary()
-        : TestLibrary("max_bytes.fidl", R"FIDL(
-library fidl.test.maxbytes;
-
-struct OneBool {
-  bool b;
-};
-
-struct OptionalOneBool {
-  OneBool? s;
-};
-
-struct TwoBools {
-  bool a;
-  bool b;
-};
-
-struct OptionalTwoBools {
-  TwoBools? s;
-};
-
-struct BoolAndU32 {
-  bool b;
-  uint32 u;
-};
-
-struct OptionalBoolAndU32 {
-  BoolAndU32? s;
-};
-
-struct BoolAndU64 {
-  bool b;
-  uint64 u;
-};
-
-struct OptionalBoolAndU64 {
-  BoolAndU64? s;
-};
-
-union UnionOfThings {
-  OneBool ob;
-  BoolAndU64 bu;
-};
-
-struct OptionalUnion {
-  UnionOfThings? u;
-};
-
-struct PaddedVector {
-  vector<int32>:3 pv;
-};
-
-struct UnboundedVector {
-  vector<int32> uv;
-};
-
-struct UnboundedVectors {
-  vector<int32> uv1;
-  vector<int32> uv2;
-};
-
-struct ShortString {
-  string:5 s;
-};
-
-struct UnboundedString {
-  string s;
-};
-
-struct AnArray {
-  array<int64>:5 a;
-};
-
-table TableWithNoMembers {
-};
-
-table TableWithOneBool {
-  1: bool b;
-};
-
-table TableWithOptionalOneBool {
-  1: OneBool s;
-};
-
-table TableWithOptionalTableWithOneBool {
-  1: TableWithOneBool s;
-};
-
-table TableWithTwoBools {
-  1: bool a;
-  2: bool b;
-};
-
-table TableWithOptionalTwoBools {
-  1: TwoBools s;
-};
-
-table TableWithOptionalTableWithTwoBools {
-  1: TableWithTwoBools s;
-};
-
-table TableWithBoolAndU32 {
-  1: bool b;
-  2: uint32 u;
-};
-
-table TableWithOptionalBoolAndU32 {
-  1: BoolAndU32 s;
-};
-
-table TableWithOptionalTableWithBoolAndU32 {
-  1: TableWithBoolAndU32 s;
-};
-
-table TableWithBoolAndU64 {
-  1: bool b;
-  2: uint64 u;
-};
-
-table TableWithOptionalBoolAndU64 {
-  1: BoolAndU64 s;
-};
-
-table TableWithOptionalTableWithBoolAndU64 {
-  1: TableWithBoolAndU64 s;
-};
-
-table TableWithOptionalUnion {
-  1: UnionOfThings u;
-};
-
-table TableWithPaddedVector {
-  1: vector<int32>:3 pv;
-};
-
-table TableWithUnboundedVector {
-  1: vector<int32> uv;
-};
-
-table TableWithUnboundedVectors {
-  1: vector<int32> uv1;
-  2: vector<int32> uv2;
-};
-
-table TableWithShortString {
-  1: string:5 s;
-};
-
-table TableWithUnboundedString {
-  1: string s;
-};
-
-table TableWithAnArray {
-  1: array<int64>:5 a;
-};
-
-xunion EmptyXUnion {
-};
-
-xunion XUnionWithOneBool {
-  bool b;
-};
-
-xunion XUnionWithBoolAndU32 {
-  bool b;
-  uint32 u;
-};
-
-xunion XUnionWithBoundedOutOfLineObject {
-  // smaller than |v| below, so will not be selected for max-out-of-line
-  // calculation.
-  bool b;
-
-  // 1. vector<int32>:5 = 20 bytes
-  //                    = 24 bytes for 8-byte boundary alignment
-  //                    +  8 bytes for vector element count
-  //                    +  8 bytes for data pointer
-  //                    = 40 bytes total
-  // 1. vector<vector<int32>:5>:6 = vector<int32>:5 (40) * 6
-  //                              = 240 bytes
-  //                              +   8 bytes for vector element count
-  //                              +   8 bytes for data pointer
-  //                              = 256 bytes total
-  vector<vector<int32>:5>:6 v;
-};
-
-xunion XUnionWithUnboundedOutOfLineObject {
-  string s;
-};
-
-struct StructWithOptionalEmptyXUnion {
-  EmptyXUnion? opt_empty;
-};
-
-protocol SomeProtocol {};
-
-struct UsingSomeProtocol {
-  SomeProtocol value;
-};
-
-struct UsingOptSomeProtocol {
-  SomeProtocol? value;
-};
-
-struct UsingRequestSomeProtocol {
-  request<SomeProtocol> value;
-};
-
-struct UsingOptRequestSomeProtocol {
-  request<SomeProtocol>? value;
-};
-
-)FIDL") {}
-};
-
-static bool simple_structs() {
-    BEGIN_TEST;
-
-    MaxBytesLibrary test_library;
-    EXPECT_TRUE(test_library.Compile());
-
-    auto one_bool = test_library.LookupStruct("OneBool");
-    EXPECT_NONNULL(one_bool);
-    EXPECT_EQ(one_bool->typeshape.Size(), 1);
-    EXPECT_EQ(one_bool->typeshape.MaxOutOfLine(), 0);
-
-    auto two_bools = test_library.LookupStruct("TwoBools");
-    EXPECT_NONNULL(two_bools);
-    EXPECT_EQ(two_bools->typeshape.Size(), 2);
-    EXPECT_EQ(two_bools->typeshape.MaxOutOfLine(), 0);
-
-    auto bool_and_u32 = test_library.LookupStruct("BoolAndU32");
-    EXPECT_NONNULL(bool_and_u32);
-    EXPECT_EQ(bool_and_u32->typeshape.Size(), 8);
-    EXPECT_EQ(bool_and_u32->typeshape.MaxOutOfLine(), 0);
-
-    auto bool_and_u64 = test_library.LookupStruct("BoolAndU64");
-    EXPECT_NONNULL(bool_and_u64);
-    EXPECT_EQ(bool_and_u64->typeshape.Size(), 16);
-    EXPECT_EQ(bool_and_u64->typeshape.MaxOutOfLine(), 0);
-
-    END_TEST;
-}
-
-static bool simple_tables() {
-    BEGIN_TEST;
-
-    MaxBytesLibrary test_library;
-    EXPECT_TRUE(test_library.Compile());
-
-    auto no_members = test_library.LookupTable("TableWithNoMembers");
-    EXPECT_NONNULL(no_members);
-    EXPECT_EQ(no_members->typeshape.Size(), 16);
-    EXPECT_EQ(no_members->typeshape.MaxOutOfLine(), 0);
-
-    auto one_bool = test_library.LookupTable("TableWithOneBool");
-    EXPECT_NONNULL(one_bool);
-    EXPECT_EQ(one_bool->typeshape.Size(), 16);
-    EXPECT_EQ(one_bool->typeshape.MaxOutOfLine(), 24);
-
-    auto two_bools = test_library.LookupTable("TableWithTwoBools");
-    EXPECT_NONNULL(two_bools);
-    EXPECT_EQ(two_bools->typeshape.Size(), 16);
-    EXPECT_EQ(two_bools->typeshape.MaxOutOfLine(), 48);
-
-    auto bool_and_u32 = test_library.LookupTable("TableWithBoolAndU32");
-    EXPECT_NONNULL(bool_and_u32);
-    EXPECT_EQ(bool_and_u32->typeshape.Size(), 16);
-    EXPECT_EQ(bool_and_u32->typeshape.MaxOutOfLine(), 48);
-
-    auto bool_and_u64 = test_library.LookupTable("TableWithBoolAndU64");
-    EXPECT_NONNULL(bool_and_u64);
-    EXPECT_EQ(bool_and_u64->typeshape.Size(), 16);
-    EXPECT_EQ(bool_and_u64->typeshape.MaxOutOfLine(), 48);
-
-    END_TEST;
-}
-
-static bool optional_structs() {
-    BEGIN_TEST;
-
-    MaxBytesLibrary test_library;
-    EXPECT_TRUE(test_library.Compile());
-
-    auto one_bool = test_library.LookupStruct("OptionalOneBool");
-    EXPECT_NONNULL(one_bool);
-    EXPECT_EQ(one_bool->typeshape.Size(), 8);
-    EXPECT_EQ(one_bool->typeshape.MaxOutOfLine(), 8);
-
-    auto two_bools = test_library.LookupStruct("OptionalTwoBools");
-    EXPECT_NONNULL(two_bools);
-    EXPECT_EQ(two_bools->typeshape.Size(), 8);
-    EXPECT_EQ(two_bools->typeshape.MaxOutOfLine(), 8);
-
-    auto bool_and_u32 = test_library.LookupStruct("OptionalBoolAndU32");
-    EXPECT_NONNULL(bool_and_u32);
-    EXPECT_EQ(bool_and_u32->typeshape.Size(), 8);
-    EXPECT_EQ(bool_and_u32->typeshape.MaxOutOfLine(), 8);
-
-    auto bool_and_u64 = test_library.LookupStruct("OptionalBoolAndU64");
-    EXPECT_NONNULL(bool_and_u64);
-    EXPECT_EQ(bool_and_u64->typeshape.Size(), 8);
-    EXPECT_EQ(bool_and_u64->typeshape.MaxOutOfLine(), 16);
-
-    END_TEST;
-}
-
-static bool optional_tables() {
-    BEGIN_TEST;
-
-    MaxBytesLibrary test_library;
-    EXPECT_TRUE(test_library.Compile());
-
-    auto one_bool = test_library.LookupTable("TableWithOptionalOneBool");
-    EXPECT_NONNULL(one_bool);
-    EXPECT_EQ(one_bool->typeshape.Size(), 16);
-    EXPECT_EQ(one_bool->typeshape.MaxOutOfLine(), 24);
-
-    auto table_with_one_bool = test_library.LookupTable("TableWithOptionalTableWithOneBool");
-    EXPECT_NONNULL(table_with_one_bool);
-    EXPECT_EQ(table_with_one_bool->typeshape.Size(), 16);
-    EXPECT_EQ(table_with_one_bool->typeshape.MaxOutOfLine(), 56);
-
-    auto two_bools = test_library.LookupTable("TableWithOptionalTwoBools");
-    EXPECT_NONNULL(two_bools);
-    EXPECT_EQ(two_bools->typeshape.Size(), 16);
-    EXPECT_EQ(two_bools->typeshape.MaxOutOfLine(), 24);
-
-    auto table_with_two_bools = test_library.LookupTable("TableWithOptionalTableWithTwoBools");
-    EXPECT_NONNULL(table_with_two_bools);
-    EXPECT_EQ(table_with_two_bools->typeshape.Size(), 16);
-    EXPECT_EQ(table_with_two_bools->typeshape.MaxOutOfLine(), 80);
-
-    auto bool_and_u32 = test_library.LookupTable("TableWithOptionalBoolAndU32");
-    EXPECT_NONNULL(bool_and_u32);
-    EXPECT_EQ(bool_and_u32->typeshape.Size(), 16);
-    EXPECT_EQ(bool_and_u32->typeshape.MaxOutOfLine(), 24);
-
-    auto table_with_bool_and_u32 = test_library.LookupTable("TableWithOptionalTableWithBoolAndU32");
-    EXPECT_NONNULL(table_with_bool_and_u32);
-    EXPECT_EQ(table_with_bool_and_u32->typeshape.Size(), 16);
-    EXPECT_EQ(table_with_bool_and_u32->typeshape.MaxOutOfLine(), 80);
-
-    auto bool_and_u64 = test_library.LookupTable("TableWithOptionalBoolAndU64");
-    EXPECT_NONNULL(bool_and_u64);
-    EXPECT_EQ(bool_and_u64->typeshape.Size(), 16);
-    EXPECT_EQ(bool_and_u64->typeshape.MaxOutOfLine(), 32);
-
-    auto table_with_bool_and_u64 = test_library.LookupTable("TableWithOptionalTableWithBoolAndU64");
-    EXPECT_NONNULL(table_with_bool_and_u64);
-    EXPECT_EQ(table_with_bool_and_u64->typeshape.Size(), 16);
-    EXPECT_EQ(table_with_bool_and_u64->typeshape.MaxOutOfLine(), 80);
-
-    END_TEST;
-}
-
-static bool unions() {
-    BEGIN_TEST;
-
-    MaxBytesLibrary test_library;
-    EXPECT_TRUE(test_library.Compile());
-
-    auto a_union = test_library.LookupUnion("UnionOfThings");
-    EXPECT_NONNULL(a_union);
-    EXPECT_EQ(a_union->typeshape.Size(), 24);
-    EXPECT_EQ(a_union->typeshape.MaxOutOfLine(), 0);
-
-    auto optional_union = test_library.LookupStruct("OptionalUnion");
-    EXPECT_NONNULL(optional_union);
-    EXPECT_EQ(optional_union->typeshape.Size(), 8);
-    EXPECT_EQ(optional_union->typeshape.MaxOutOfLine(), 24);
-
-    auto table_with_optional_union = test_library.LookupTable("TableWithOptionalUnion");
-    EXPECT_NONNULL(table_with_optional_union);
-    EXPECT_EQ(table_with_optional_union->typeshape.Size(), 16);
-    EXPECT_EQ(table_with_optional_union->typeshape.MaxOutOfLine(), 40);
-
-    END_TEST;
-}
-
-static bool vectors() {
-    BEGIN_TEST;
-
-    MaxBytesLibrary test_library;
-    EXPECT_TRUE(test_library.Compile());
-
-    auto padded_vector = test_library.LookupStruct("PaddedVector");
-    EXPECT_NONNULL(padded_vector);
-    EXPECT_EQ(padded_vector->typeshape.Size(), 16);
-    EXPECT_EQ(padded_vector->typeshape.MaxOutOfLine(), 16);
-
-    auto unbounded_vector = test_library.LookupStruct("UnboundedVector");
-    EXPECT_NONNULL(unbounded_vector);
-    EXPECT_EQ(unbounded_vector->typeshape.Size(), 16);
-    EXPECT_EQ(unbounded_vector->typeshape.MaxOutOfLine(), std::numeric_limits<uint32_t>::max());
-
-    auto unbounded_vectors = test_library.LookupStruct("UnboundedVectors");
-    EXPECT_NONNULL(unbounded_vectors);
-    EXPECT_EQ(unbounded_vectors->typeshape.Size(), 32);
-    EXPECT_EQ(unbounded_vectors->typeshape.MaxOutOfLine(), std::numeric_limits<uint32_t>::max());
-
-    auto table_with_padded_vector = test_library.LookupTable("TableWithPaddedVector");
-    EXPECT_NONNULL(table_with_padded_vector);
-    EXPECT_EQ(table_with_padded_vector->typeshape.Size(), 16);
-    EXPECT_EQ(table_with_padded_vector->typeshape.MaxOutOfLine(), 48);
-
-    auto table_with_unbounded_vector = test_library.LookupTable("TableWithUnboundedVector");
-    EXPECT_NONNULL(table_with_unbounded_vector);
-    EXPECT_EQ(table_with_unbounded_vector->typeshape.Size(), 16);
-    EXPECT_EQ(table_with_unbounded_vector->typeshape.MaxOutOfLine(), std::numeric_limits<uint32_t>::max());
-
-    auto table_with_unbounded_vectors = test_library.LookupTable("TableWithUnboundedVectors");
-    EXPECT_NONNULL(table_with_unbounded_vectors);
-    EXPECT_EQ(table_with_unbounded_vectors->typeshape.Size(), 16);
-    EXPECT_EQ(table_with_unbounded_vectors->typeshape.MaxOutOfLine(), std::numeric_limits<uint32_t>::max());
-
-    END_TEST;
-}
-
-static bool strings() {
-    BEGIN_TEST;
-
-    MaxBytesLibrary test_library;
-    EXPECT_TRUE(test_library.Compile());
-
-    auto short_string = test_library.LookupStruct("ShortString");
-    EXPECT_NONNULL(short_string);
-    EXPECT_EQ(short_string->typeshape.Size(), 16);
-    EXPECT_EQ(short_string->typeshape.MaxOutOfLine(), 8);
-
-    auto unbounded_string = test_library.LookupStruct("UnboundedString");
-    EXPECT_NONNULL(unbounded_string);
-    EXPECT_EQ(unbounded_string->typeshape.Size(), 16);
-    EXPECT_EQ(unbounded_string->typeshape.MaxOutOfLine(), std::numeric_limits<uint32_t>::max());
-
-    auto table_with_short_string = test_library.LookupTable("TableWithShortString");
-    EXPECT_NONNULL(table_with_short_string);
-    EXPECT_EQ(table_with_short_string->typeshape.Size(), 16);
-    EXPECT_EQ(table_with_short_string->typeshape.MaxOutOfLine(), 40);
-
-    auto table_with_unbounded_string = test_library.LookupTable("TableWithUnboundedString");
-    EXPECT_NONNULL(table_with_unbounded_string);
-    EXPECT_EQ(table_with_unbounded_string->typeshape.Size(), 16);
-    EXPECT_EQ(table_with_unbounded_string->typeshape.MaxOutOfLine(), std::numeric_limits<uint32_t>::max());
-
-    END_TEST;
-}
-
-static bool arrays() {
-    BEGIN_TEST;
-
-    MaxBytesLibrary test_library;
-    EXPECT_TRUE(test_library.Compile());
-
-    auto an_array = test_library.LookupStruct("AnArray");
-    EXPECT_NONNULL(an_array);
-    EXPECT_EQ(an_array->typeshape.Size(), 40);
-    EXPECT_EQ(an_array->typeshape.MaxOutOfLine(), 0);
-
-    auto table_with_an_array = test_library.LookupTable("TableWithAnArray");
-    EXPECT_NONNULL(table_with_an_array);
-    EXPECT_EQ(table_with_an_array->typeshape.Size(), 16);
-    EXPECT_EQ(table_with_an_array->typeshape.MaxOutOfLine(), 56);
-
-    END_TEST;
-}
-
-static bool xunions() {
-    BEGIN_TEST;
-
-    MaxBytesLibrary test_library;
-    EXPECT_TRUE(test_library.Compile());
-
-    auto empty = test_library.LookupXUnion("EmptyXUnion");
-    EXPECT_EQ(empty->typeshape.Size(), 24);
-    EXPECT_EQ(empty->typeshape.MaxOutOfLine(), 0);
-
-    auto one_bool = test_library.LookupXUnion("XUnionWithOneBool");
-    EXPECT_EQ(one_bool->typeshape.Size(), 24);
-    EXPECT_EQ(one_bool->typeshape.MaxOutOfLine(), 8);
-
-    auto xu = test_library.LookupXUnion("XUnionWithBoundedOutOfLineObject");
-    EXPECT_EQ(xu->typeshape.Size(), 24);
-    EXPECT_EQ(xu->typeshape.MaxOutOfLine(), 256);
-
-    auto unbounded = test_library.LookupXUnion("XUnionWithUnboundedOutOfLineObject");
-    EXPECT_EQ(unbounded->typeshape.Size(), 24);
-    EXPECT_EQ(unbounded->typeshape.MaxOutOfLine(), std::numeric_limits<uint32_t>::max());
-
-    auto opt_empty = test_library.LookupStruct("StructWithOptionalEmptyXUnion");
-    EXPECT_EQ(opt_empty->typeshape.Size(), 24);
-    EXPECT_EQ(opt_empty->typeshape.MaxOutOfLine(), 0);
-
-    END_TEST;
-}
-
-bool protocols_and_request_of_protocols() {
-    BEGIN_TEST;
-
-    MaxBytesLibrary test_library;
-    EXPECT_TRUE(test_library.Compile());
-
-    auto using_some_protocol = test_library.LookupStruct("UsingSomeProtocol");
-    EXPECT_NONNULL(using_some_protocol);
-    EXPECT_EQ(using_some_protocol->typeshape.Size(), 4);
-    EXPECT_EQ(using_some_protocol->typeshape.Alignment(), 4);
-    EXPECT_EQ(using_some_protocol->typeshape.MaxOutOfLine(), 0);
-
-    auto using_opt_some_protocol = test_library.LookupStruct("UsingOptSomeProtocol");
-    EXPECT_NONNULL(using_opt_some_protocol);
-    EXPECT_EQ(using_opt_some_protocol->typeshape.Size(), 4);
-    EXPECT_EQ(using_opt_some_protocol->typeshape.Alignment(), 4);
-    EXPECT_EQ(using_opt_some_protocol->typeshape.MaxOutOfLine(), 0);
-
-    auto using_request_some_protocol = test_library.LookupStruct("UsingRequestSomeProtocol");
-    EXPECT_NONNULL(using_request_some_protocol);
-    EXPECT_EQ(using_request_some_protocol->typeshape.Size(), 4);
-    EXPECT_EQ(using_request_some_protocol->typeshape.Alignment(), 4);
-    EXPECT_EQ(using_request_some_protocol->typeshape.MaxOutOfLine(), 0);
-
-    auto using_opt_request_some_protocol = test_library.LookupStruct("UsingOptRequestSomeProtocol");
-    EXPECT_NONNULL(using_opt_request_some_protocol);
-    EXPECT_EQ(using_opt_request_some_protocol->typeshape.Size(), 4);
-    EXPECT_EQ(using_opt_request_some_protocol->typeshape.Alignment(), 4);
-    EXPECT_EQ(using_opt_request_some_protocol->typeshape.MaxOutOfLine(), 0);
-
-    END_TEST;
-}
-
-bool recursive_request() {
-  BEGIN_TEST;
-
-  TestLibrary library(R"FIDL(
-library example;
-
-struct WebMessage {
-  request<MessagePort> message_port_req;
-};
-
-protocol MessagePort {
-  PostMessage(WebMessage message) -> (bool success);
-};
-)FIDL");
-  ASSERT_TRUE(library.Compile());
-
-  auto web_message = library.LookupStruct("WebMessage");
-  EXPECT_NONNULL(web_message);
-  EXPECT_EQ(web_message->typeshape.Size(), 4);
-  EXPECT_EQ(web_message->typeshape.Alignment(), 4);
-  EXPECT_EQ(web_message->typeshape.MaxOutOfLine(), 0);
-  EXPECT_EQ(web_message->typeshape.MaxHandles(), 1);
-  EXPECT_EQ(web_message->typeshape.Depth(), 0);
-
-  auto message_port = library.LookupInterface("MessagePort");
-  EXPECT_NONNULL(message_port);
-  EXPECT_EQ(message_port->methods.size(), 1);
-  auto& post_message = message_port->methods[0];
-  auto post_message_request = post_message.maybe_request;
-  EXPECT_NONNULL(post_message_request);
-  EXPECT_EQ(post_message_request->typeshape.Size(), 24);
-  EXPECT_EQ(post_message_request->typeshape.Alignment(), 8);
-  EXPECT_EQ(post_message_request->typeshape.MaxOutOfLine(), 0);
-  EXPECT_EQ(post_message_request->typeshape.MaxHandles(), 1);
-  EXPECT_EQ(post_message_request->typeshape.Depth(), 0);
-
-  END_TEST;
-}
-
-bool recursive_opt_request() {
-  BEGIN_TEST;
-
-  TestLibrary library(R"FIDL(
-library example;
-
-struct WebMessage {
-  request<MessagePort>? opt_message_port_req;
-};
-
-protocol MessagePort {
-  PostMessage(WebMessage message) -> (bool success);
-};
-)FIDL");
-  ASSERT_TRUE(library.Compile());
-
-  auto web_message = library.LookupStruct("WebMessage");
-  EXPECT_NONNULL(web_message);
-  EXPECT_EQ(web_message->typeshape.Size(), 4);
-  EXPECT_EQ(web_message->typeshape.Alignment(), 4);
-  EXPECT_EQ(web_message->typeshape.MaxOutOfLine(), 0);
-  EXPECT_EQ(web_message->typeshape.MaxHandles(), 1);
-  EXPECT_EQ(web_message->typeshape.Depth(), 0);
-
-  auto message_port = library.LookupInterface("MessagePort");
-  EXPECT_NONNULL(message_port);
-  EXPECT_EQ(message_port->methods.size(), 1);
-  auto& post_message = message_port->methods[0];
-  auto post_message_request = post_message.maybe_request;
-  EXPECT_NONNULL(post_message_request);
-  EXPECT_EQ(post_message_request->typeshape.Size(), 24);
-  EXPECT_EQ(post_message_request->typeshape.Alignment(), 8);
-  EXPECT_EQ(post_message_request->typeshape.MaxOutOfLine(), 0);
-  EXPECT_EQ(post_message_request->typeshape.MaxHandles(), 1);
-  EXPECT_EQ(post_message_request->typeshape.Depth(), 0);
-
-  END_TEST;
-}
-
-bool recursive_protocol() {
-  BEGIN_TEST;
-
-  TestLibrary library(R"FIDL(
-library example;
-
-struct WebMessage {
-  MessagePort message_port;
-};
-
-protocol MessagePort {
-  PostMessage(WebMessage message) -> (bool success);
-};
-)FIDL");
-  ASSERT_TRUE(library.Compile());
-
-  auto web_message = library.LookupStruct("WebMessage");
-  EXPECT_NONNULL(web_message);
-  EXPECT_EQ(web_message->typeshape.Size(), 4);
-  EXPECT_EQ(web_message->typeshape.Alignment(), 4);
-  EXPECT_EQ(web_message->typeshape.MaxOutOfLine(), 0);
-  EXPECT_EQ(web_message->typeshape.MaxHandles(), 1);
-  EXPECT_EQ(web_message->typeshape.Depth(), 0);
-
-  auto message_port = library.LookupInterface("MessagePort");
-  EXPECT_NONNULL(message_port);
-  EXPECT_EQ(message_port->methods.size(), 1);
-  auto& post_message = message_port->methods[0];
-  auto post_message_request = post_message.maybe_request;
-  EXPECT_NONNULL(post_message_request);
-  EXPECT_EQ(post_message_request->typeshape.Size(), 24);
-  EXPECT_EQ(post_message_request->typeshape.Alignment(), 8);
-  EXPECT_EQ(post_message_request->typeshape.MaxOutOfLine(), 0);
-  EXPECT_EQ(post_message_request->typeshape.MaxHandles(), 1);
-  EXPECT_EQ(post_message_request->typeshape.Depth(), 0);
-
-  END_TEST;
-}
-
-bool recursive_opt_protocol() {
-  BEGIN_TEST;
-
-  TestLibrary library(R"FIDL(
-library example;
-
-struct WebMessage {
-  MessagePort? opt_message_port;
-};
-
-protocol MessagePort {
-  PostMessage(WebMessage message) -> (bool success);
-};
-)FIDL");
-  ASSERT_TRUE(library.Compile());
-
-  auto web_message = library.LookupStruct("WebMessage");
-  EXPECT_NONNULL(web_message);
-  EXPECT_EQ(web_message->typeshape.Size(), 4);
-  EXPECT_EQ(web_message->typeshape.Alignment(), 4);
-  EXPECT_EQ(web_message->typeshape.MaxOutOfLine(), 0);
-  EXPECT_EQ(web_message->typeshape.MaxHandles(), 1);
-  EXPECT_EQ(web_message->typeshape.Depth(), 0);
-
-  auto message_port = library.LookupInterface("MessagePort");
-  EXPECT_NONNULL(message_port);
-  EXPECT_EQ(message_port->methods.size(), 1);
-  auto& post_message = message_port->methods[0];
-  auto post_message_request = post_message.maybe_request;
-  EXPECT_NONNULL(post_message_request);
-  EXPECT_EQ(post_message_request->typeshape.Size(), 24);
-  EXPECT_EQ(post_message_request->typeshape.Alignment(), 8);
-  EXPECT_EQ(post_message_request->typeshape.MaxOutOfLine(), 0);
-  EXPECT_EQ(post_message_request->typeshape.MaxHandles(), 1);
-  EXPECT_EQ(post_message_request->typeshape.Depth(), 0);
-
-  END_TEST;
-}
-
-bool recursive_struct() {
-  BEGIN_TEST;
-
-  TestLibrary library(R"FIDL(
-library example;
-
-struct TheStruct {
-  TheStruct? opt_one_more;
-};
-)FIDL");
-  ASSERT_TRUE(library.Compile());
-
-  auto the_struct = library.LookupStruct("TheStruct");
-  EXPECT_NONNULL(the_struct);
-  EXPECT_EQ(the_struct->typeshape.Size(), 8);
-  EXPECT_EQ(the_struct->typeshape.Alignment(), 8);
-  // TODO(FIDL-457): Imprecision here, max out-ofline should be infinite.
-  EXPECT_EQ(the_struct->typeshape.MaxOutOfLine(), 0);
-  // TODO(FIDL-457): Incorrectly saturating, there are no handles here.
-  EXPECT_EQ(the_struct->typeshape.MaxHandles(), std::numeric_limits<uint32_t>::max());
-  EXPECT_EQ(the_struct->typeshape.Depth(), std::numeric_limits<uint32_t>::max());
-
-  END_TEST;
-}
-
-bool recursive_struct_with_handles() {
-  BEGIN_TEST;
-
-  TestLibrary library(R"FIDL(
-library example;
-
-struct TheStruct {
-  handle<vmo> some_handle;
-  TheStruct? opt_one_more;
-};
-)FIDL");
-  ASSERT_TRUE(library.Compile());
-
-  auto the_struct = library.LookupStruct("TheStruct");
-  EXPECT_NONNULL(the_struct);
-  EXPECT_EQ(the_struct->typeshape.Size(), 16);
-  EXPECT_EQ(the_struct->typeshape.Alignment(), 8);
-  // TODO(FIDL-457): Imprecision here, max out-ofline should be infinite.
-  EXPECT_EQ(the_struct->typeshape.MaxOutOfLine(), 0);
-  EXPECT_EQ(the_struct->typeshape.MaxHandles(), std::numeric_limits<uint32_t>::max());
-  EXPECT_EQ(the_struct->typeshape.Depth(), std::numeric_limits<uint32_t>::max());
-
-  END_TEST;
-}
-
-bool co_recursive_struct() {
-  BEGIN_TEST;
-
-  TestLibrary library(R"FIDL(
-library example;
-
-struct A {
-    B? foo;
-};
-
-struct B {
-    A? bar;
-};
-)FIDL");
-  ASSERT_TRUE(library.Compile());
-
-  auto struct_a = library.LookupStruct("A");
-  EXPECT_NONNULL(struct_a);
-  EXPECT_EQ(struct_a->typeshape.Size(), 8);
-  EXPECT_EQ(struct_a->typeshape.Alignment(), 8);
-  // TODO(FIDL-457): Imprecision here, max out-ofline should be infinite.
-  EXPECT_EQ(struct_a->typeshape.MaxOutOfLine(), 16);
-  // TODO(FIDL-457): Incorrectly saturating, there are no handles here.
-  EXPECT_EQ(struct_a->typeshape.MaxHandles(), std::numeric_limits<uint32_t>::max());
-  EXPECT_EQ(struct_a->typeshape.Depth(), std::numeric_limits<uint32_t>::max());
-
-  auto struct_b = library.LookupStruct("B");
-  EXPECT_NONNULL(struct_b);
-  EXPECT_EQ(struct_b->typeshape.Size(), 8);
-  EXPECT_EQ(struct_b->typeshape.Alignment(), 8);
-  // TODO(FIDL-457): Imprecision here, max out-ofline should be infinite.
-  EXPECT_EQ(struct_b->typeshape.MaxOutOfLine(), 8);
-  // TODO(FIDL-457): Incorrectly saturating, there are no handles here.
-  EXPECT_EQ(struct_b->typeshape.MaxHandles(), std::numeric_limits<uint32_t>::max());
-  EXPECT_EQ(struct_b->typeshape.Depth(), std::numeric_limits<uint32_t>::max());
-
-  END_TEST;
-}
-
-bool co_recursive_struct_with_handles() {
-  BEGIN_TEST;
-
-  TestLibrary library(R"FIDL(
-library example;
-
-struct A {
-    handle a;
-    B? foo;
-};
-
-struct B {
-    handle b;
-    A? bar;
-};
-)FIDL");
-  ASSERT_TRUE(library.Compile());
-
-  auto struct_a = library.LookupStruct("A");
-  EXPECT_NONNULL(struct_a);
-  EXPECT_EQ(struct_a->typeshape.Size(), 16);
-  EXPECT_EQ(struct_a->typeshape.Alignment(), 8);
-  // TODO(FIDL-457): Imprecision here, max out-ofline should be infinite.
-  EXPECT_EQ(struct_a->typeshape.MaxOutOfLine(), 32);
-  EXPECT_EQ(struct_a->typeshape.MaxHandles(), std::numeric_limits<uint32_t>::max());
-  EXPECT_EQ(struct_a->typeshape.Depth(), std::numeric_limits<uint32_t>::max());
-
-  auto struct_b = library.LookupStruct("B");
-  EXPECT_NONNULL(struct_b);
-  EXPECT_EQ(struct_b->typeshape.Size(), 16);
-  EXPECT_EQ(struct_b->typeshape.Alignment(), 8);
-  // TODO(FIDL-457): Imprecision here, max out-ofline should be infinite.
-  EXPECT_EQ(struct_b->typeshape.MaxOutOfLine(), 16);
-  EXPECT_EQ(struct_b->typeshape.MaxHandles(), std::numeric_limits<uint32_t>::max());
-  EXPECT_EQ(struct_b->typeshape.Depth(), std::numeric_limits<uint32_t>::max());
-
-  END_TEST;
-}
-
-bool co_recursive_struct2() {
-  BEGIN_TEST;
-
-  TestLibrary library(R"FIDL(
-library example;
-
-struct Foo {
-    Bar b;
-};
-
-struct Bar {
-    Foo? f;
-};
-)FIDL");
-  ASSERT_TRUE(library.Compile());
-
-  auto struct_foo = library.LookupStruct("Foo");
-  EXPECT_NONNULL(struct_foo);
-  EXPECT_EQ(struct_foo->typeshape.Size(), 8);
-  EXPECT_EQ(struct_foo->typeshape.Alignment(), 8);
-  // TODO(FIDL-457): Imprecision here, max out-ofline should be infinite.
-  EXPECT_EQ(struct_foo->typeshape.MaxOutOfLine(), 0);
-  // TODO(FIDL-457): Incorrectly saturating, there are no handles here.
-  EXPECT_EQ(struct_foo->typeshape.MaxHandles(), std::numeric_limits<uint32_t>::max());
-  EXPECT_EQ(struct_foo->typeshape.Depth(), std::numeric_limits<uint32_t>::max());
-
-  auto struct_bar = library.LookupStruct("Bar");
-  EXPECT_NONNULL(struct_bar);
-  EXPECT_EQ(struct_bar->typeshape.Size(), 8);
-  EXPECT_EQ(struct_bar->typeshape.Alignment(), 8);
-  // TODO(FIDL-457): Imprecision here, max out-ofline should be infinite.
-  EXPECT_EQ(struct_bar->typeshape.MaxOutOfLine(), 0);
-  // TODO(FIDL-457): Incorrectly saturating, there are no handles here.
-  EXPECT_EQ(struct_bar->typeshape.MaxHandles(), std::numeric_limits<uint32_t>::max());
-  EXPECT_EQ(struct_bar->typeshape.Depth(), std::numeric_limits<uint32_t>::max());
-
-  END_TEST;
-}
-
-bool struct_two_deep() {
-  BEGIN_TEST;
-
-  TestLibrary library(R"FIDL(
-library example;
-
-struct DiffEntry {
-    vector<uint8>:256 key;
-
-    Value? base;
-    Value? left;
-    Value? right;
-};
-
-struct Value {
-    Buffer? value;
-    Priority priority;
-};
-
-struct Buffer {
-    handle<vmo> vmo;
-    uint64 size;
-};
-
-enum Priority {
-    EAGER = 0;
-    LAZY = 1;
-};
-)FIDL");
-  ASSERT_TRUE(library.Compile());
-
-  auto buffer = library.LookupStruct("Buffer");
-  EXPECT_NONNULL(buffer);
-  EXPECT_EQ(buffer->typeshape.Size(), 16);
-  EXPECT_EQ(buffer->typeshape.Alignment(), 8);
-  EXPECT_EQ(buffer->typeshape.MaxOutOfLine(), 0);
-  EXPECT_EQ(buffer->typeshape.MaxHandles(), 1);
-  EXPECT_EQ(buffer->typeshape.Depth(), 0);
-
-  auto value = library.LookupStruct("Value");
-  EXPECT_NONNULL(value);
-  EXPECT_EQ(value->typeshape.Size(), 16);
-  EXPECT_EQ(value->typeshape.Alignment(), 8);
-  EXPECT_EQ(value->typeshape.MaxOutOfLine(), 16);
-  EXPECT_EQ(buffer->typeshape.MaxHandles(), 1);
-  EXPECT_EQ(value->typeshape.Depth(), 1);
-
-  auto diff_entry = library.LookupStruct("DiffEntry");
-  EXPECT_NONNULL(diff_entry);
-  EXPECT_EQ(diff_entry->typeshape.Size(), 40);
-  EXPECT_EQ(diff_entry->typeshape.Alignment(), 8);
-  EXPECT_EQ(diff_entry->typeshape.MaxOutOfLine(), 352);
-  // TODO(FIDL-457): max 3 handles, since each Value has one.
-  EXPECT_EQ(buffer->typeshape.MaxHandles(), 1);
-  EXPECT_EQ(diff_entry->typeshape.Depth(), 2);
-
-  END_TEST;
-}
-
-bool protocol_child_and_parent() {
-  BEGIN_TEST;
-
-  SharedAmongstLibraries shared;
-  TestLibrary parent_library("parent.fidl", R"FIDL(
-library parent;
-
-[FragileBase]
-protocol Parent {
-  Sync() -> ();
-};
-)FIDL", &shared);
-  ASSERT_TRUE(parent_library.Compile());
-
-  TestLibrary child_library("child.fidl", R"FIDL(
-library child;
-
-using parent;
-
-protocol Child {
-  compose parent.Parent;
-};
-)FIDL", &shared);
-  ASSERT_TRUE(child_library.AddDependentLibrary(std::move(parent_library)));
-  ASSERT_TRUE(child_library.Compile());
-
-  auto child = child_library.LookupInterface("Child");
-  EXPECT_NONNULL(child);
-  EXPECT_EQ(child->all_methods.size(), 1);
-  auto& sync = child->all_methods[0];
-  auto sync_request = sync->maybe_request;
-  EXPECT_NONNULL(sync_request);
-  EXPECT_EQ(sync_request->typeshape.Size(), 16);
-  EXPECT_EQ(sync_request->typeshape.Alignment(), 8);
-  EXPECT_EQ(sync_request->typeshape.MaxOutOfLine(), 0);
-  EXPECT_EQ(sync_request->typeshape.MaxHandles(), 0);
-  EXPECT_EQ(sync_request->typeshape.Depth(), 0);
-
-  END_TEST;
-}
-
-} // namespace
-
-BEGIN_TEST_CASE(max_bytes_tests)
-RUN_TEST(simple_structs)
-RUN_TEST(simple_tables)
-RUN_TEST(optional_structs)
-RUN_TEST(optional_tables)
-RUN_TEST(unions)
-RUN_TEST(vectors)
-RUN_TEST(strings)
-RUN_TEST(arrays)
-RUN_TEST(xunions)
-RUN_TEST(protocols_and_request_of_protocols)
-RUN_TEST(recursive_request)
-RUN_TEST(recursive_opt_request)
-RUN_TEST(recursive_protocol)
-RUN_TEST(recursive_opt_protocol)
-RUN_TEST(recursive_struct)
-RUN_TEST(recursive_struct_with_handles)
-RUN_TEST(co_recursive_struct)
-RUN_TEST(co_recursive_struct_with_handles)
-RUN_TEST(co_recursive_struct2)
-RUN_TEST(struct_two_deep)
-RUN_TEST(protocol_child_and_parent)
-END_TEST_CASE(max_bytes_tests)
diff --git a/zircon/system/utest/fidl-compiler/max_handle_tests.cpp b/zircon/system/utest/fidl-compiler/max_handle_tests.cpp
deleted file mode 100644
index 49d77ed..0000000
--- a/zircon/system/utest/fidl-compiler/max_handle_tests.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <unittest/unittest.h>
-
-#include <fidl/flat_ast.h>
-#include <fidl/lexer.h>
-#include <fidl/parser.h>
-#include <fidl/source_file.h>
-
-#include "test_library.h"
-
-namespace {
-
-class MaxHandlesLibrary : public TestLibrary {
-public:
-    MaxHandlesLibrary()
-        : TestLibrary("max_handles.fidl", R"FIDL(
-library fidl.test.maxhandles;
-
-struct OneBool {
-  bool b;
-};
-
-struct OneHandle {
-  handle h;
-};
-
-struct HandleArray {
-  array<handle>:8 ha;
-};
-
-struct NullableHandleArray {
-  array<handle?>:8 ha;
-};
-
-struct HandleVector {
-  vector<handle>:8 hv;
-};
-
-struct HandleNullableVector {
-  vector<handle>:8? hv;
-};
-
-struct UnboundedHandleVector {
-  vector<handle> hv;
-};
-
-struct HandleStructVector {
-  vector<OneHandle>:8 sv;
-};
-
-struct HandleTableVector {
-  vector<TableWithOneHandle>:8 sv;
-};
-
-table TableWithNoMembers {
-};
-
-table TableWithOneBool {
-  1: bool b;
-};
-
-table TableWithOneHandle {
-  1: handle h;
-};
-
-table TableWithHandleArray {
-  1: array<handle>:8 ha;
-};
-
-table TableWithNullableHandleArray {
-  1: array<handle?>:8 ha;
-};
-
-table TableWithHandleVector {
-  1: vector<handle>:8 hv;
-};
-
-table TableWithUnboundedHandleVector {
-  1: vector<handle> hv;
-};
-
-table TableWithHandleStructVector {
-  1: vector<OneHandle>:8 sv;
-};
-
-table TableWithHandleTableVector {
-  1: vector<OneHandle>:8 sv;
-};
-
-union NoHandleUnion {
-  OneBool one_bool;
-  uint32 integer;
-};
-
-union OneHandleUnion {
-  OneHandle one_handle;
-  OneBool one_bool;
-  uint32 integer;
-};
-
-union ManyHandleUnion {
-  OneHandle one_handle;
-  HandleArray handle_array;
-  HandleVector handle_vector;
-};
-
-)FIDL") {}
-};
-
-static bool simple_structs(void) {
-    BEGIN_TEST;
-
-    MaxHandlesLibrary test_library;
-    EXPECT_TRUE(test_library.Compile());
-
-    auto one_bool = test_library.LookupStruct("OneBool");
-    EXPECT_NONNULL(one_bool);
-    EXPECT_EQ(one_bool->typeshape.MaxHandles(), 0);
-
-    auto one_handle = test_library.LookupStruct("OneHandle");
-    EXPECT_NONNULL(one_handle);
-    EXPECT_EQ(one_handle->typeshape.MaxHandles(), 1);
-
-    END_TEST;
-}
-
-static bool simple_tables(void) {
-    BEGIN_TEST;
-
-    MaxHandlesLibrary test_library;
-    EXPECT_TRUE(test_library.Compile());
-
-    auto no_members = test_library.LookupTable("TableWithNoMembers");
-    EXPECT_NONNULL(no_members);
-    EXPECT_EQ(no_members->typeshape.MaxHandles(), 0);
-
-    auto one_bool = test_library.LookupTable("TableWithOneBool");
-    EXPECT_NONNULL(one_bool);
-    EXPECT_EQ(one_bool->typeshape.MaxHandles(), 0);
-
-    auto one_handle = test_library.LookupTable("TableWithOneHandle");
-    EXPECT_NONNULL(one_handle);
-    EXPECT_EQ(one_handle->typeshape.MaxHandles(), 1);
-
-    END_TEST;
-}
-
-static bool arrays(void) {
-    BEGIN_TEST;
-
-    MaxHandlesLibrary test_library;
-    EXPECT_TRUE(test_library.Compile());
-
-    auto handle_array = test_library.LookupStruct("HandleArray");
-    EXPECT_NONNULL(handle_array);
-    EXPECT_EQ(handle_array->typeshape.MaxHandles(), 8);
-
-    auto table_with_handle_array = test_library.LookupTable("TableWithHandleArray");
-    EXPECT_NONNULL(table_with_handle_array);
-    EXPECT_EQ(table_with_handle_array->typeshape.MaxHandles(), 8);
-
-    auto nullable_handle_array = test_library.LookupStruct("NullableHandleArray");
-    EXPECT_NONNULL(nullable_handle_array);
-    EXPECT_EQ(nullable_handle_array->typeshape.MaxHandles(), 8);
-
-    auto table_with_nullable_handle_array = test_library.LookupTable("TableWithNullableHandleArray");
-    EXPECT_NONNULL(table_with_nullable_handle_array);
-    EXPECT_EQ(table_with_nullable_handle_array->typeshape.MaxHandles(), 8);
-
-    END_TEST;
-}
-
-static bool vectors(void) {
-    BEGIN_TEST;
-
-    MaxHandlesLibrary test_library;
-    EXPECT_TRUE(test_library.Compile());
-
-    auto handle_vector = test_library.LookupStruct("HandleVector");
-    EXPECT_NONNULL(handle_vector);
-    EXPECT_EQ(handle_vector->typeshape.MaxHandles(), 8);
-
-    auto table_with_handle_vector = test_library.LookupTable("TableWithHandleVector");
-    EXPECT_NONNULL(table_with_handle_vector);
-    EXPECT_EQ(table_with_handle_vector->typeshape.MaxHandles(), 8);
-
-    auto handle_nullable_vector = test_library.LookupStruct("HandleNullableVector");
-    EXPECT_NONNULL(handle_nullable_vector);
-    EXPECT_EQ(handle_nullable_vector->typeshape.MaxHandles(), 8);
-
-    auto unbounded_handle_vector = test_library.LookupStruct("UnboundedHandleVector");
-    EXPECT_NONNULL(unbounded_handle_vector);
-    EXPECT_EQ(unbounded_handle_vector->typeshape.MaxHandles(), std::numeric_limits<uint32_t>::max());
-
-    auto table_with_unbounded_handle_vector = test_library.LookupTable("TableWithUnboundedHandleVector");
-    EXPECT_NONNULL(table_with_unbounded_handle_vector);
-    EXPECT_EQ(table_with_unbounded_handle_vector->typeshape.MaxHandles(), std::numeric_limits<uint32_t>::max());
-
-    auto handle_struct_vector = test_library.LookupStruct("HandleStructVector");
-    EXPECT_NONNULL(handle_struct_vector);
-    EXPECT_EQ(handle_struct_vector->typeshape.MaxHandles(), 8);
-
-    auto handle_table_vector = test_library.LookupStruct("HandleTableVector");
-    EXPECT_NONNULL(handle_table_vector);
-    EXPECT_EQ(handle_table_vector->typeshape.MaxHandles(), 8);
-
-    auto table_with_handle_struct_vector = test_library.LookupTable("TableWithHandleStructVector");
-    EXPECT_NONNULL(table_with_handle_struct_vector);
-    EXPECT_EQ(table_with_handle_struct_vector->typeshape.MaxHandles(), 8);
-
-    END_TEST;
-}
-
-static bool unions(void) {
-    BEGIN_TEST;
-
-    MaxHandlesLibrary test_library;
-    EXPECT_TRUE(test_library.Compile());
-
-    auto no_handle_union = test_library.LookupUnion("NoHandleUnion");
-    EXPECT_NONNULL(no_handle_union);
-    EXPECT_EQ(no_handle_union->typeshape.MaxHandles(), 0);
-
-    auto one_handle_union = test_library.LookupUnion("OneHandleUnion");
-    EXPECT_NONNULL(one_handle_union);
-    EXPECT_EQ(one_handle_union->typeshape.MaxHandles(), 1);
-
-    auto many_handle_union = test_library.LookupUnion("ManyHandleUnion");
-    EXPECT_NONNULL(many_handle_union);
-    EXPECT_EQ(many_handle_union->typeshape.MaxHandles(), 8);
-
-    END_TEST;
-}
-
-} // namespace
-
-BEGIN_TEST_CASE(max_handles_tests)
-RUN_TEST(simple_structs)
-RUN_TEST(simple_tables)
-RUN_TEST(arrays)
-RUN_TEST(vectors)
-RUN_TEST(unions)
-END_TEST_CASE(max_handles_tests)
diff --git a/zircon/system/utest/fidl-compiler/optionals_tests.cpp b/zircon/system/utest/fidl-compiler/optionals_tests.cpp
deleted file mode 100644
index d1c58d6..0000000
--- a/zircon/system/utest/fidl-compiler/optionals_tests.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <unittest/unittest.h>
-
-#include <fidl/flat_ast.h>
-#include <fidl/lexer.h>
-#include <fidl/parser.h>
-#include <fidl/source_file.h>
-
-#include "test_library.h"
-
-namespace {
-
-bool test_no_optional_on_primitive() {
-    BEGIN_TEST;
-
-    TestLibrary library(R"FIDL(
-library test.optionals;
-
-struct Bad {
-    int64? opt_num;
-};
-
-)FIDL");
-    ASSERT_FALSE(library.Compile());
-    const auto& errors = library.errors();
-    ASSERT_EQ(1, errors.size());
-    ASSERT_STR_STR(errors[0].c_str(),
-        "int64 cannot be nullable");
-
-    END_TEST;
-}
-
-bool test_no_optional_on_aliased_primitive() {
-    BEGIN_TEST;
-
-    TestLibrary library(R"FIDL(
-library test.optionals;
-
-using alias = int64;
-
-struct Bad {
-    alias? opt_num;
-};
-
-)FIDL");
-    ASSERT_FALSE(library.Compile());
-    const auto& errors = library.errors();
-    ASSERT_EQ(1, errors.size());
-    ASSERT_STR_STR(errors[0].c_str(),
-        "int64 cannot be nullable");
-
-    END_TEST;
-}
-
-} // namespace
-
-BEGIN_TEST_CASE(optionals_test)
-RUN_TEST(test_no_optional_on_primitive)
-RUN_TEST(test_no_optional_on_aliased_primitive)
-END_TEST_CASE(optionals_test)
diff --git a/zircon/system/utest/fidl-compiler/ordinals_tests.cpp b/zircon/system/utest/fidl-compiler/ordinals_tests.cpp
index 4c54794..784b5f1 100644
--- a/zircon/system/utest/fidl-compiler/ordinals_tests.cpp
+++ b/zircon/system/utest/fidl-compiler/ordinals_tests.cpp
@@ -81,7 +81,7 @@
     END_TEST;
 }
 
-bool test_clashing_ordinal_values() {
+bool clashing_ordinal_values() {
     BEGIN_TEST;
 
     TestLibrary library(R"FIDL(
@@ -108,7 +108,7 @@
     END_TEST;
 }
 
-bool test_clashing_ordinal_values_with_attribute() {
+bool clashing_ordinal_values_with_attribute() {
     BEGIN_TEST;
 
     TestLibrary library(R"FIDL(
@@ -157,7 +157,7 @@
     END_TEST;
 }
 
-bool test_ordinal_value_is_sha256() {
+bool ordinal_value_is_sha256() {
     BEGIN_TEST;
     TestLibrary library(R"FIDL(
 library a;
@@ -183,8 +183,8 @@
 
 BEGIN_TEST_CASE(ordinals_test)
 RUN_TEST(ordinal_cannot_be_zero)
-RUN_TEST(test_clashing_ordinal_values)
-RUN_TEST(test_clashing_ordinal_values_with_attribute)
+RUN_TEST(clashing_ordinal_values)
+RUN_TEST(clashing_ordinal_values_with_attribute)
 RUN_TEST(attribute_resolves_clashes)
-RUN_TEST(test_ordinal_value_is_sha256)
+RUN_TEST(ordinal_value_is_sha256)
 END_TEST_CASE(ordinals_test)
diff --git a/zircon/system/utest/fidl-compiler/parsing_tests.cpp b/zircon/system/utest/fidl-compiler/parsing_tests.cpp
index 0f20ba8..5507fde 100644
--- a/zircon/system/utest/fidl-compiler/parsing_tests.cpp
+++ b/zircon/system/utest/fidl-compiler/parsing_tests.cpp
@@ -247,10 +247,8 @@
 static bool invalid_character_test(void) {
     BEGIN_TEST;
 
-    class InvalidCharacterLibrary : public TestLibrary {
-    public:
-        InvalidCharacterLibrary()
-            : TestLibrary("invalid.character.fidl", R"FIDL(
+    LocaleSwapper swapper("de_DE.iso88591");
+    TestLibrary test_library("invalid.character.fidl", R"FIDL(
 library fidl.test.maxbytes;
 
 // This is all alphanumeric in the appropriate locale, but not a valid
@@ -259,13 +257,8 @@
     int32 x;
 };
 
-)FIDL") {}
-    } test_library;
-
-    {
-        LocaleSwapper("de_DE.iso88591");
-        EXPECT_FALSE(test_library.Compile());
-    }
+)FIDL");
+    ASSERT_FALSE(test_library.Compile());
 
     const auto& errors = test_library.errors();
     EXPECT_NE(errors.size(), 0);
diff --git a/zircon/system/utest/fidl-compiler/test_library.h b/zircon/system/utest/fidl-compiler/test_library.h
index 1caad53..2d38faf 100644
--- a/zircon/system/utest/fidl-compiler/test_library.h
+++ b/zircon/system/utest/fidl-compiler/test_library.h
@@ -28,11 +28,22 @@
     fidl::ErrorReporter error_reporter;
     fidl::flat::Typespace typespace;
     fidl::flat::Libraries all_libraries;
-    std::set<std::unique_ptr<fidl::SourceFile>> all_sources;
+    std::vector<std::unique_ptr<fidl::SourceFile>> all_sources_of_all_libraries;
 };
 
-class TestLibrary {
+class TestLibrary final {
 public:
+    explicit TestLibrary()
+        : TestLibrary(&owned_shared_) {}
+
+    explicit TestLibrary(SharedAmongstLibraries* shared)
+        : error_reporter_(&shared->error_reporter),
+          typespace_(&shared->typespace),
+          all_libraries_(&shared->all_libraries),
+          all_sources_of_all_libraries_(&shared->all_sources_of_all_libraries),
+          library_(std::make_unique<fidl::flat::Library>(
+              all_libraries_, error_reporter_, typespace_)) {}
+
     explicit TestLibrary(const std::string& raw_source_code)
         : TestLibrary("example.fidl", raw_source_code) {}
 
@@ -41,15 +52,14 @@
 
     TestLibrary(const std::string& filename, const std::string& raw_source_code,
                 SharedAmongstLibraries* shared)
-        : error_reporter_(&shared->error_reporter),
-          typespace_(&shared->typespace),
-          all_libraries_(&shared->all_libraries),
-          all_sources_(&shared->all_sources),
-          library_(std::make_unique<fidl::flat::Library>(
-              all_libraries_, error_reporter_, typespace_)) {
+        : TestLibrary(shared) {
+        AddSource(filename, raw_source_code);
+    }
+
+    void AddSource(const std::string& filename, const std::string& raw_source_code) {
         auto source_file = MakeSourceFile(filename, raw_source_code);
-        source_file_ = source_file.get();
-        all_sources_->insert(std::move(source_file));
+        all_sources_.push_back(source_file.get());
+        all_sources_of_all_libraries_->push_back(std::move(source_file));
     }
 
     bool AddDependentLibrary(TestLibrary dependent_library) {
@@ -60,29 +70,39 @@
         all_libraries_->AddAttributeSchema(name, std::move(schema));
     }
 
-    bool Parse(std::unique_ptr<fidl::raw::File>& ast_ptr) {
-        fidl::Lexer lexer(*source_file_, error_reporter_);
+    // TODO(pascallouis): remove, this does not use a library.
+    bool Parse(std::unique_ptr<fidl::raw::File>* out_ast_ptr) {
+        assert(all_sources_.size() == 1 && "parse can only be used with one source");
+        auto source_file = all_sources_.at(0);
+        fidl::Lexer lexer(*source_file, error_reporter_);
         fidl::Parser parser(&lexer, error_reporter_);
-        ast_ptr.reset(parser.Parse().release());
+        out_ast_ptr->reset(parser.Parse().release());
         return parser.Ok();
     }
 
     bool Compile() {
-        fidl::Lexer lexer(*source_file_, error_reporter_);
-        fidl::Parser parser(&lexer, error_reporter_);
-        auto ast = parser.Parse();
-        return parser.Ok() &&
-               library_->ConsumeFile(std::move(ast)) &&
-               library_->Compile();
+        for (auto source_file : all_sources_) {
+            fidl::Lexer lexer(*source_file, error_reporter_);
+            fidl::Parser parser(&lexer, error_reporter_);
+            auto ast = parser.Parse();
+            if (!parser.Ok())
+                return false;
+            if (!library_->ConsumeFile(std::move(ast)))
+                return false;
+        }
+        return library_->Compile();
     }
 
+    // TODO(pascallouis): remove, this does not use a library.
     bool Lint(fidl::Findings* findings) {
-        fidl::Lexer lexer(*source_file_, error_reporter_);
+        assert(all_sources_.size() == 1 && "lint can only be used with one source");
+        auto source_file = all_sources_.at(0);
+        fidl::Lexer lexer(*source_file, error_reporter_);
         fidl::Parser parser(&lexer, error_reporter_);
         auto ast = parser.Parse();
         if (!parser.Ok()) {
-            std::string_view beginning(source_file_->data().data(), 0);
-            fidl::SourceLocation source_location(beginning, *source_file_);
+            std::string_view beginning(source_file->data().data(), 0);
+            fidl::SourceLocation source_location(beginning, *source_file);
             findings->emplace_back(source_location, "parser-error",
                                    error_reporter_->errors().front() + "\n");
             return false;
@@ -104,16 +124,6 @@
         return out.str();
     }
 
-    bool AddSourceFile(const std::string& filename, const std::string& raw_source_code) {
-        auto source_file = MakeSourceFile(filename, raw_source_code);
-        fidl::Lexer lexer(*source_file, error_reporter_);
-        fidl::Parser parser(&lexer, error_reporter_);
-        auto ast = parser.Parse();
-        return parser.Ok() &&
-               library_->ConsumeFile(std::move(ast)) &&
-               library_->Compile();
-    }
-
     const fidl::flat::Bits* LookupBits(const std::string& name) {
         for (const auto& bits_decl : library_->bits_declarations_) {
             if (bits_decl->GetName() == name) {
@@ -186,36 +196,8 @@
     }
 
     const fidl::SourceFile& source_file() const {
-        return *source_file_;
-    }
-
-    std::string filename() const {
-        return std::string(source_file().filename());
-    }
-
-    std::string FileData() const {
-        return std::string(source_file().data());
-    }
-
-    std::string FileLocation(std::string within, std::string to_find) const {
-        std::istringstream lines(within);
-        std::string line;
-        size_t line_number = 0;
-        while (std::getline(lines, line)) {
-            line_number++;
-            size_t column_index = line.find(to_find);
-            if (column_index != std::string::npos) {
-                std::stringstream position;
-                position << filename() << ":" << line_number << ":" << (column_index + 1);
-                return position.str();
-            }
-        }
-        assert(false); // Bug in test
-        return "never reached";
-    }
-
-    std::string FileLocation(std::string to_find) const {
-        return FileLocation(FileData(), to_find);
+        assert(all_sources_.size() == 1 && "convenience method only possible with single source");
+        return *all_sources_.at(0);
     }
 
     const std::vector<std::string>& errors() const {
@@ -235,8 +217,8 @@
     fidl::ErrorReporter* error_reporter_;
     fidl::flat::Typespace* typespace_;
     fidl::flat::Libraries* all_libraries_;
-    std::set<std::unique_ptr<fidl::SourceFile>>* all_sources_;
-    fidl::SourceFile* source_file_;
+    std::vector<std::unique_ptr<fidl::SourceFile>>* all_sources_of_all_libraries_;
+    std::vector<fidl::SourceFile*> all_sources_;
     std::unique_ptr<fidl::flat::Library> library_;
 };
 
diff --git a/zircon/system/utest/fidl-compiler/type_alias_tests.cpp b/zircon/system/utest/fidl-compiler/type_alias_tests.cpp
index eb2281b..c08e72db 100644
--- a/zircon/system/utest/fidl-compiler/type_alias_tests.cpp
+++ b/zircon/system/utest/fidl-compiler/type_alias_tests.cpp
@@ -62,6 +62,48 @@
     END_TEST;
 }
 
+bool invalid_no_optional_on_primitive() {
+    BEGIN_TEST;
+
+    TestLibrary library(R"FIDL(
+library test.optionals;
+
+struct Bad {
+    int64? opt_num;
+};
+
+)FIDL");
+    ASSERT_FALSE(library.Compile());
+    const auto& errors = library.errors();
+    ASSERT_EQ(1, errors.size());
+    ASSERT_STR_STR(errors[0].c_str(),
+        "int64 cannot be nullable");
+
+    END_TEST;
+}
+
+bool invalid_no_optional_on_aliased_primitive() {
+    BEGIN_TEST;
+
+    TestLibrary library(R"FIDL(
+library test.optionals;
+
+using alias = int64;
+
+struct Bad {
+    alias? opt_num;
+};
+
+)FIDL");
+    ASSERT_FALSE(library.Compile());
+    const auto& errors = library.errors();
+    ASSERT_EQ(1, errors.size());
+    ASSERT_STR_STR(errors[0].c_str(),
+        "int64 cannot be nullable");
+
+    END_TEST;
+}
+
 bool vector_parametrized_on_decl() {
     BEGIN_TEST;
 
@@ -304,6 +346,8 @@
 BEGIN_TEST_CASE(type_alias_tests)
 RUN_TEST(primitive)
 RUN_TEST(primitive_type_alias_before_use)
+RUN_TEST(invalid_no_optional_on_primitive)
+RUN_TEST(invalid_no_optional_on_aliased_primitive)
 RUN_TEST(vector_parametrized_on_decl)
 RUN_TEST(vector_parametrized_on_use)
 RUN_TEST(vector_bounded_on_decl)
diff --git a/zircon/system/utest/fidl-compiler/typeshape_tests.cpp b/zircon/system/utest/fidl-compiler/typeshape_tests.cpp
new file mode 100644
index 0000000..5f1caf8
--- /dev/null
+++ b/zircon/system/utest/fidl-compiler/typeshape_tests.cpp
@@ -0,0 +1,1652 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <unittest/unittest.h>
+
+#include <fidl/flat_ast.h>
+#include <fidl/lexer.h>
+#include <fidl/parser.h>
+#include <fidl/source_file.h>
+
+#include "test_library.h"
+
+namespace {
+
+struct Expected {
+    uint32_t size = 0;
+    uint32_t alignment = 0;
+    uint32_t max_out_of_line = 0;
+    uint32_t max_handles = 0;
+    uint32_t depth = 0;
+};
+
+bool CheckTypeShape(const TypeShape& actual, Expected expected) {
+    BEGIN_HELPER;
+    EXPECT_EQ(actual.Size(), expected.size);
+    EXPECT_EQ(actual.Alignment(), expected.alignment);
+    EXPECT_EQ(actual.MaxOutOfLine(), expected.max_out_of_line);
+    EXPECT_EQ(actual.MaxHandles(), expected.max_handles);
+    EXPECT_EQ(actual.Depth(), expected.depth);
+    END_HELPER;
+}
+
+static bool simple_structs() {
+    BEGIN_TEST;
+
+    TestLibrary test_library(R"FIDL(
+library example;
+
+struct OneBool {
+  bool b;
+};
+
+struct TwoBools {
+  bool a;
+  bool b;
+};
+
+struct BoolAndU32 {
+  bool b;
+  uint32 u;
+};
+
+struct BoolAndU64 {
+  bool b;
+  uint64 u;
+};
+    )FIDL");
+    ASSERT_TRUE(test_library.Compile());
+
+    auto one_bool = test_library.LookupStruct("OneBool");
+    ASSERT_NONNULL(one_bool);
+    EXPECT_TRUE(CheckTypeShape(one_bool->typeshape, Expected {
+        .size = 1,
+        .alignment = 1,
+    }));
+
+    auto two_bools = test_library.LookupStruct("TwoBools");
+    ASSERT_NONNULL(two_bools);
+    EXPECT_TRUE(CheckTypeShape(two_bools->typeshape, Expected {
+        .size = 2,
+        .alignment = 1,
+    }));
+
+    auto bool_and_u32 = test_library.LookupStruct("BoolAndU32");
+    ASSERT_NONNULL(bool_and_u32);
+    EXPECT_TRUE(CheckTypeShape(bool_and_u32->typeshape, Expected {
+        .size = 8,
+        .alignment = 4,
+    }));
+
+    auto bool_and_u64 = test_library.LookupStruct("BoolAndU64");
+    ASSERT_NONNULL(bool_and_u64);
+    EXPECT_TRUE(CheckTypeShape(bool_and_u64->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+    }));
+
+    END_TEST;
+}
+
+static bool simple_structs_with_handles() {
+    BEGIN_TEST;
+
+    TestLibrary test_library(R"FIDL(
+library example;
+
+struct OneHandle {
+  handle h;
+};
+
+struct TwoHandles {
+  handle<channel> h1;
+  handle<port> h2;
+};
+
+struct ThreeHandlesOneOptional {
+  handle<channel> h1;
+  handle<port> h2;
+  handle<timer>? opt_h3;
+};
+
+    )FIDL");
+    ASSERT_TRUE(test_library.Compile());
+
+    auto one_handle = test_library.LookupStruct("OneHandle");
+    ASSERT_NONNULL(one_handle);
+    EXPECT_TRUE(CheckTypeShape(one_handle->typeshape, Expected {
+        .size = 4,
+        .alignment = 4,
+        .max_handles = 1,
+    }));
+
+    auto two_handles = test_library.LookupStruct("TwoHandles");
+    ASSERT_NONNULL(two_handles);
+    EXPECT_TRUE(CheckTypeShape(two_handles->typeshape, Expected {
+        .size = 8,
+        .alignment = 4,
+        .max_handles = 2,
+    }));
+
+    auto three_handles_one_optional = test_library.LookupStruct("ThreeHandlesOneOptional");
+    ASSERT_NONNULL(three_handles_one_optional);
+    EXPECT_TRUE(CheckTypeShape(three_handles_one_optional->typeshape, Expected {
+        .size = 12,
+        .alignment = 4,
+        .max_handles = 3,
+    }));
+
+    END_TEST;
+}
+
+static bool simple_tables() {
+    BEGIN_TEST;
+
+    TestLibrary test_library(R"FIDL(
+library example;
+
+table TableWithNoMembers {
+};
+
+table TableWithOneBool {
+  1: bool b;
+};
+
+table TableWithTwoBools {
+  1: bool a;
+  2: bool b;
+};
+
+table TableWithBoolAndU32 {
+  1: bool b;
+  2: uint32 u;
+};
+
+table TableWithBoolAndU64 {
+  1: bool b;
+  2: uint64 u;
+};
+
+    )FIDL");
+    ASSERT_TRUE(test_library.Compile());
+
+    auto no_members = test_library.LookupTable("TableWithNoMembers");
+    ASSERT_NONNULL(no_members);
+    EXPECT_TRUE(CheckTypeShape(no_members->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .depth = 4294967295, // TODO(FIDL-457): wrong.
+    }));
+
+    auto one_bool = test_library.LookupTable("TableWithOneBool");
+    ASSERT_NONNULL(one_bool);
+    EXPECT_TRUE(CheckTypeShape(one_bool->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 24,
+        .depth = 3, // TODO(FIDL-457): wrong.
+    }));
+
+    auto two_bools = test_library.LookupTable("TableWithTwoBools");
+    ASSERT_NONNULL(two_bools);
+    EXPECT_TRUE(CheckTypeShape(two_bools->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 48,
+        .depth = 3, // TODO(FIDL-457): wrong.
+    }));
+
+    auto bool_and_u32 = test_library.LookupTable("TableWithBoolAndU32");
+    ASSERT_NONNULL(bool_and_u32);
+    EXPECT_TRUE(CheckTypeShape(bool_and_u32->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 48,
+        .depth = 3, // TODO(FIDL-457): wrong.
+    }));
+
+    auto bool_and_u64 = test_library.LookupTable("TableWithBoolAndU64");
+    ASSERT_NONNULL(bool_and_u64);
+    EXPECT_TRUE(CheckTypeShape(bool_and_u32->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 48,
+        .depth = 3, // TODO(FIDL-457): wrong.
+    }));
+
+    END_TEST;
+}
+
+static bool simple_tables_with_handles() {
+    BEGIN_TEST;
+
+    TestLibrary test_library(R"FIDL(
+library example;
+
+table TableWithOneHandle {
+  1: handle h;
+};
+
+    )FIDL");
+    ASSERT_TRUE(test_library.Compile());
+
+    auto one_handle = test_library.LookupTable("TableWithOneHandle");
+    ASSERT_NONNULL(one_handle);
+    EXPECT_TRUE(CheckTypeShape(one_handle->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 24,
+        .max_handles = 1,
+        .depth = 3,
+    }));
+
+    END_TEST;
+}
+
+static bool optional_structs() {
+    BEGIN_TEST;
+
+    TestLibrary test_library(R"FIDL(
+library example;
+
+struct OneBool {
+  bool b;
+};
+
+struct OptionalOneBool {
+  OneBool? s;
+};
+
+struct TwoBools {
+  bool a;
+  bool b;
+};
+
+struct OptionalTwoBools {
+  TwoBools? s;
+};
+
+struct BoolAndU32 {
+  bool b;
+  uint32 u;
+};
+
+struct OptionalBoolAndU32 {
+  BoolAndU32? s;
+};
+
+struct BoolAndU64 {
+  bool b;
+  uint64 u;
+};
+
+struct OptionalBoolAndU64 {
+  BoolAndU64? s;
+};
+
+    )FIDL");
+    ASSERT_TRUE(test_library.Compile());
+
+    auto one_bool = test_library.LookupStruct("OptionalOneBool");
+    ASSERT_NONNULL(one_bool);
+    EXPECT_TRUE(CheckTypeShape(one_bool->typeshape, Expected {
+        .size = 8,
+        .alignment = 8,
+        .max_out_of_line = 8,
+        .depth = 1,
+    }));
+
+    auto two_bools = test_library.LookupStruct("OptionalTwoBools");
+    ASSERT_NONNULL(two_bools);
+    EXPECT_TRUE(CheckTypeShape(two_bools->typeshape, Expected {
+        .size = 8,
+        .alignment = 8,
+        .max_out_of_line = 8,
+        .depth = 1,
+    }));
+
+    auto bool_and_u32 = test_library.LookupStruct("OptionalBoolAndU32");
+    ASSERT_NONNULL(bool_and_u32);
+    EXPECT_TRUE(CheckTypeShape(bool_and_u32->typeshape, Expected {
+        .size = 8,
+        .alignment = 8,
+        .max_out_of_line = 8,
+        .depth = 1,
+    }));
+
+    auto bool_and_u64 = test_library.LookupStruct("OptionalBoolAndU64");
+    ASSERT_NONNULL(bool_and_u64);
+    EXPECT_TRUE(CheckTypeShape(bool_and_u64->typeshape, Expected {
+        .size = 8,
+        .alignment = 8,
+        .max_out_of_line = 16,
+        .depth = 1,
+    }));
+
+    END_TEST;
+}
+
+static bool optional_tables() {
+    BEGIN_TEST;
+
+    TestLibrary test_library(R"FIDL(
+library example;
+
+struct OneBool {
+  bool b;
+};
+
+table TableWithOptionalOneBool {
+  1: OneBool s;
+};
+
+table TableWithOneBool {
+  1: bool b;
+};
+
+table TableWithOptionalTableWithOneBool {
+  1: TableWithOneBool s;
+};
+
+struct TwoBools {
+  bool a;
+  bool b;
+};
+
+table TableWithOptionalTwoBools {
+  1: TwoBools s;
+};
+
+table TableWithTwoBools {
+  1: bool a;
+  2: bool b;
+};
+
+table TableWithOptionalTableWithTwoBools {
+  1: TableWithTwoBools s;
+};
+
+struct BoolAndU32 {
+  bool b;
+  uint32 u;
+};
+
+table TableWithOptionalBoolAndU32 {
+  1: BoolAndU32 s;
+};
+
+table TableWithBoolAndU32 {
+  1: bool b;
+  2: uint32 u;
+};
+
+table TableWithOptionalTableWithBoolAndU32 {
+  1: TableWithBoolAndU32 s;
+};
+
+struct BoolAndU64 {
+  bool b;
+  uint64 u;
+};
+
+table TableWithOptionalBoolAndU64 {
+  1: BoolAndU64 s;
+};
+
+table TableWithBoolAndU64 {
+  1: bool b;
+  2: uint64 u;
+};
+
+table TableWithOptionalTableWithBoolAndU64 {
+  1: TableWithBoolAndU64 s;
+};
+
+    )FIDL");
+    ASSERT_TRUE(test_library.Compile());
+
+    auto one_bool = test_library.LookupTable("TableWithOptionalOneBool");
+    ASSERT_NONNULL(one_bool);
+    EXPECT_TRUE(CheckTypeShape(one_bool->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 24,
+        .depth = 3, // TODO(FIDL-457): wrong.
+    }));
+
+    auto table_with_one_bool = test_library.LookupTable("TableWithOptionalTableWithOneBool");
+    ASSERT_NONNULL(table_with_one_bool);
+    EXPECT_TRUE(CheckTypeShape(table_with_one_bool->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 56,
+        .depth = 6, // TODO(FIDL-457): wrong.
+    }));
+
+    auto two_bools = test_library.LookupTable("TableWithOptionalTwoBools");
+    ASSERT_NONNULL(two_bools);
+    EXPECT_TRUE(CheckTypeShape(two_bools->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 24,
+        .depth = 3, // TODO(FIDL-457): wrong.
+    }));
+
+    auto table_with_two_bools = test_library.LookupTable("TableWithOptionalTableWithTwoBools");
+    ASSERT_NONNULL(table_with_two_bools);
+    EXPECT_TRUE(CheckTypeShape(table_with_two_bools->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 80,
+        .depth = 6, // TODO(FIDL-457): wrong.
+    }));
+
+    auto bool_and_u32 = test_library.LookupTable("TableWithOptionalBoolAndU32");
+    ASSERT_NONNULL(bool_and_u32);
+    EXPECT_TRUE(CheckTypeShape(bool_and_u32->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 24,
+        .depth = 3, // TODO(FIDL-457): wrong.
+    }));
+
+    auto table_with_bool_and_u32 = test_library.LookupTable("TableWithOptionalTableWithBoolAndU32");
+    ASSERT_NONNULL(table_with_bool_and_u32);
+    EXPECT_TRUE(CheckTypeShape(table_with_bool_and_u32->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 80,
+        .depth = 6, // TODO(FIDL-457): wrong.
+    }));
+
+    auto bool_and_u64 = test_library.LookupTable("TableWithOptionalBoolAndU64");
+    ASSERT_NONNULL(bool_and_u64);
+    EXPECT_TRUE(CheckTypeShape(bool_and_u64->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 32,
+        .depth = 3, // TODO(FIDL-457): wrong.
+    }));
+
+    auto table_with_bool_and_u64 = test_library.LookupTable("TableWithOptionalTableWithBoolAndU64");
+    ASSERT_NONNULL(table_with_bool_and_u64);
+    EXPECT_TRUE(CheckTypeShape(table_with_bool_and_u64->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 80,
+        .depth = 6, // TODO(FIDL-457): wrong.
+    }));
+
+    END_TEST;
+}
+
+static bool unions() {
+    BEGIN_TEST;
+
+    TestLibrary test_library(R"FIDL(
+library example;
+
+struct BoolAndU64 {
+  bool b;
+  uint64 u;
+};
+
+union UnionOfThings {
+  bool ob;
+  BoolAndU64 bu;
+};
+
+struct OptionalUnion {
+  UnionOfThings? u;
+};
+
+table TableWithOptionalUnion {
+  1: UnionOfThings u;
+};
+
+    )FIDL");
+    ASSERT_TRUE(test_library.Compile());
+
+    auto a_union = test_library.LookupUnion("UnionOfThings");
+    ASSERT_NONNULL(a_union);
+    EXPECT_TRUE(CheckTypeShape(a_union->typeshape, Expected {
+        .size = 24,
+        .alignment = 8,
+    }));
+
+    auto optional_union = test_library.LookupStruct("OptionalUnion");
+    ASSERT_NONNULL(optional_union);
+    EXPECT_TRUE(CheckTypeShape(optional_union->typeshape, Expected {
+        .size = 8,
+        .alignment = 8,
+        .max_out_of_line = 24,
+        .depth = 1,
+    }));
+
+    auto table_with_optional_union = test_library.LookupTable("TableWithOptionalUnion");
+    ASSERT_NONNULL(table_with_optional_union);
+    EXPECT_TRUE(CheckTypeShape(table_with_optional_union->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 40,
+        .depth = 3,
+    }));
+
+    END_TEST;
+}
+
+static bool unions_with_handles() {
+    BEGIN_TEST;
+
+    TestLibrary test_library(R"FIDL(
+library example;
+
+union OneHandleUnion {
+  handle one_handle;
+  bool one_bool;
+  uint32 one_int;
+};
+
+union ManyHandleUnion {
+  handle one_handle;
+  array<handle>:8 handle_array;
+  vector<handle>:8 handle_vector;
+};
+
+    )FIDL");
+    ASSERT_TRUE(test_library.Compile());
+
+    auto one_handle_union = test_library.LookupUnion("OneHandleUnion");
+    ASSERT_NONNULL(one_handle_union);
+    EXPECT_TRUE(CheckTypeShape(one_handle_union->typeshape, Expected {
+        .size = 8,
+        .alignment = 4,
+        .max_handles = 1,
+    }));
+
+    auto many_handle_union = test_library.LookupUnion("ManyHandleUnion");
+    ASSERT_NONNULL(many_handle_union);
+    EXPECT_TRUE(CheckTypeShape(many_handle_union->typeshape, Expected {
+        .size = 40,
+        .alignment = 8,
+        .max_out_of_line = 32,
+        .max_handles = 8,
+        .depth = 1,
+    }));
+
+    END_TEST;
+}
+
+static bool vectors() {
+    BEGIN_TEST;
+
+    TestLibrary test_library(R"FIDL(
+library example;
+
+struct PaddedVector {
+  vector<int32>:3 pv;
+};
+
+struct UnboundedVector {
+  vector<int32> uv;
+};
+
+struct UnboundedVectors {
+  vector<int32> uv1;
+  vector<int32> uv2;
+};
+
+table TableWithPaddedVector {
+  1: vector<int32>:3 pv;
+};
+
+table TableWithUnboundedVector {
+  1: vector<int32> uv;
+};
+
+table TableWithUnboundedVectors {
+  1: vector<int32> uv1;
+  2: vector<int32> uv2;
+};
+
+    )FIDL");
+    ASSERT_TRUE(test_library.Compile());
+
+    auto padded_vector = test_library.LookupStruct("PaddedVector");
+    ASSERT_NONNULL(padded_vector);
+    EXPECT_TRUE(CheckTypeShape(padded_vector->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 16,
+        .depth = 1,
+    }));
+
+    auto unbounded_vector = test_library.LookupStruct("UnboundedVector");
+    ASSERT_NONNULL(unbounded_vector);
+    EXPECT_TRUE(CheckTypeShape(unbounded_vector->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = std::numeric_limits<uint32_t>::max(),
+        .depth = 1,
+    }));
+
+    auto unbounded_vectors = test_library.LookupStruct("UnboundedVectors");
+    ASSERT_NONNULL(unbounded_vectors);
+    EXPECT_TRUE(CheckTypeShape(unbounded_vectors->typeshape, Expected {
+        .size = 32,
+        .alignment = 8,
+        .max_out_of_line = std::numeric_limits<uint32_t>::max(),
+        .depth = 1,
+    }));
+
+    auto table_with_padded_vector = test_library.LookupTable("TableWithPaddedVector");
+    ASSERT_NONNULL(table_with_padded_vector);
+    EXPECT_TRUE(CheckTypeShape(table_with_padded_vector->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 48,
+        .depth = 4, // TODO(FIDL-457): wrong.
+    }));
+
+    auto table_with_unbounded_vector = test_library.LookupTable("TableWithUnboundedVector");
+    ASSERT_NONNULL(table_with_unbounded_vector);
+    EXPECT_TRUE(CheckTypeShape(table_with_unbounded_vector->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = std::numeric_limits<uint32_t>::max(),
+        .depth = 4, // TODO(FIDL-457): wrong.
+    }));
+
+    auto table_with_unbounded_vectors = test_library.LookupTable("TableWithUnboundedVectors");
+    ASSERT_NONNULL(table_with_unbounded_vectors);
+    EXPECT_TRUE(CheckTypeShape(table_with_unbounded_vectors->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = std::numeric_limits<uint32_t>::max(),
+        .depth = 4, // TODO(FIDL-457): wrong.
+    }));
+
+    END_TEST;
+}
+
+static bool vectors_with_handles() {
+    BEGIN_TEST;
+
+    TestLibrary test_library(R"FIDL(
+library example;
+
+struct HandleVector {
+  vector<handle>:8 hv;
+};
+
+struct HandleNullableVector {
+  vector<handle>:8? hv;
+};
+
+table TableWithHandleVector {
+  1: vector<handle>:8 hv;
+};
+
+struct UnboundedHandleVector {
+  vector<handle> hv;
+};
+
+table TableWithUnboundedHandleVector {
+  1: vector<handle> hv;
+};
+
+struct OneHandle {
+  handle h;
+};
+
+struct HandleStructVector {
+  vector<OneHandle>:8 sv;
+};
+
+table TableWithOneHandle {
+  1: handle h;
+};
+
+struct HandleTableVector {
+  vector<TableWithOneHandle>:8 sv;
+};
+
+table TableWithHandleStructVector {
+  1: vector<OneHandle>:8 sv;
+};
+
+    )FIDL");
+    ASSERT_TRUE(test_library.Compile());
+
+    auto handle_vector = test_library.LookupStruct("HandleVector");
+    ASSERT_NONNULL(handle_vector);
+    EXPECT_TRUE(CheckTypeShape(handle_vector->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 32,
+        .max_handles = 8,
+        .depth = 1,
+    }));
+
+    auto handle_nullable_vector = test_library.LookupStruct("HandleNullableVector");
+    ASSERT_NONNULL(handle_nullable_vector);
+    EXPECT_TRUE(CheckTypeShape(handle_nullable_vector->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 32,
+        .max_handles = 8,
+        .depth = 1,
+    }));
+
+    auto unbounded_handle_vector = test_library.LookupStruct("UnboundedHandleVector");
+    ASSERT_NONNULL(unbounded_handle_vector);
+    EXPECT_TRUE(CheckTypeShape(unbounded_handle_vector->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = std::numeric_limits<uint32_t>::max(),
+        .max_handles = std::numeric_limits<uint32_t>::max(),
+        .depth = 1,
+    }));
+
+    auto table_with_unbounded_handle_vector = test_library.LookupTable("TableWithUnboundedHandleVector");
+    ASSERT_NONNULL(table_with_unbounded_handle_vector);
+    EXPECT_TRUE(CheckTypeShape(table_with_unbounded_handle_vector->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = std::numeric_limits<uint32_t>::max(),
+        .max_handles = std::numeric_limits<uint32_t>::max(),
+        .depth = 4,  // TODO(FIDL-457): wrong.
+    }));
+
+    auto handle_struct_vector = test_library.LookupStruct("HandleStructVector");
+    ASSERT_NONNULL(handle_struct_vector);
+    EXPECT_TRUE(CheckTypeShape(handle_struct_vector->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 32,
+        .max_handles = 8,
+        .depth = 1,
+    }));
+
+    auto handle_table_vector = test_library.LookupStruct("HandleTableVector");
+    ASSERT_NONNULL(handle_table_vector);
+    EXPECT_TRUE(CheckTypeShape(handle_table_vector->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 320,
+        .max_handles = 8,
+        .depth = 4, // TODO(FIDL-457): wrong.
+    }));
+
+    auto table_with_handle_struct_vector = test_library.LookupTable("TableWithHandleStructVector");
+    ASSERT_NONNULL(table_with_handle_struct_vector);
+    EXPECT_TRUE(CheckTypeShape(table_with_handle_struct_vector->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 64,
+        .max_handles = 8,
+        .depth = 4, // TODO(FIDL-457): wrong.
+    }));
+
+    END_TEST;
+}
+
+static bool strings() {
+    BEGIN_TEST;
+
+    TestLibrary test_library(R"FIDL(
+library example;
+
+struct ShortString {
+  string:5 s;
+};
+
+struct UnboundedString {
+  string s;
+};
+
+table TableWithShortString {
+  1: string:5 s;
+};
+
+table TableWithUnboundedString {
+  1: string s;
+};
+
+    )FIDL");
+    ASSERT_TRUE(test_library.Compile());
+
+    auto short_string = test_library.LookupStruct("ShortString");
+    ASSERT_NONNULL(short_string);
+    EXPECT_TRUE(CheckTypeShape(short_string->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 8,
+        .depth = 1,
+    }));
+
+    auto unbounded_string = test_library.LookupStruct("UnboundedString");
+    ASSERT_NONNULL(unbounded_string);
+    EXPECT_TRUE(CheckTypeShape(unbounded_string->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = std::numeric_limits<uint32_t>::max(),
+        .depth = 1,
+    }));
+
+    auto table_with_short_string = test_library.LookupTable("TableWithShortString");
+    ASSERT_NONNULL(table_with_short_string);
+    EXPECT_TRUE(CheckTypeShape(table_with_short_string->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 40,
+        .depth = 4, // TODO(FIDL-457): wrong.
+    }));
+
+    auto table_with_unbounded_string = test_library.LookupTable("TableWithUnboundedString");
+    ASSERT_NONNULL(table_with_unbounded_string);
+    EXPECT_TRUE(CheckTypeShape(table_with_unbounded_string->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = std::numeric_limits<uint32_t>::max(),
+        .depth = 4, // TODO(FIDL-457): wrong.
+    }));
+
+    END_TEST;
+}
+
+static bool arrays() {
+    BEGIN_TEST;
+
+    TestLibrary test_library(R"FIDL(
+library example;
+
+struct AnArray {
+  array<int64>:5 a;
+};
+
+table TableWithAnArray {
+  1: array<int64>:5 a;
+};
+
+    )FIDL");
+    ASSERT_TRUE(test_library.Compile());
+
+    auto an_array = test_library.LookupStruct("AnArray");
+    ASSERT_NONNULL(an_array);
+    EXPECT_TRUE(CheckTypeShape(an_array->typeshape, Expected {
+        .size = 40,
+        .alignment = 8,
+    }));
+
+    auto table_with_an_array = test_library.LookupTable("TableWithAnArray");
+    ASSERT_NONNULL(table_with_an_array);
+    EXPECT_TRUE(CheckTypeShape(table_with_an_array->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 56,
+        .depth = 3, // TODO(FIDL-457): wrong.
+    }));
+
+    END_TEST;
+}
+
+static bool arrays_with_handles() {
+    BEGIN_TEST;
+
+    TestLibrary test_library(R"FIDL(
+library example;
+
+struct HandleArray {
+  array<handle>:8 ha;
+};
+
+table TableWithHandleArray {
+  1: array<handle>:8 ha;
+};
+
+struct NullableHandleArray {
+  array<handle?>:8 ha;
+};
+
+table TableWithNullableHandleArray {
+  1: array<handle?>:8 ha;
+};
+
+    )FIDL");
+    ASSERT_TRUE(test_library.Compile());
+
+    auto handle_array = test_library.LookupStruct("HandleArray");
+    ASSERT_NONNULL(handle_array);
+    EXPECT_TRUE(CheckTypeShape(handle_array->typeshape, Expected {
+        .size = 32,
+        .alignment = 4,
+        .max_handles = 8,
+    }));
+
+    auto table_with_handle_array = test_library.LookupTable("TableWithHandleArray");
+    ASSERT_NONNULL(table_with_handle_array);
+    EXPECT_TRUE(CheckTypeShape(table_with_handle_array->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 48,
+        .max_handles = 8,
+        .depth = 3, // TODO(FIDL-457): wrong.
+    }));
+
+    auto nullable_handle_array = test_library.LookupStruct("NullableHandleArray");
+    ASSERT_NONNULL(nullable_handle_array);
+    EXPECT_TRUE(CheckTypeShape(nullable_handle_array->typeshape, Expected {
+        .size = 32,
+        .alignment = 4,
+        .max_handles = 8,
+    }));
+
+    auto table_with_nullable_handle_array = test_library.LookupTable("TableWithNullableHandleArray");
+    ASSERT_NONNULL(table_with_nullable_handle_array);
+    EXPECT_TRUE(CheckTypeShape(table_with_nullable_handle_array->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 48,
+        .max_handles = 8,
+        .depth = 3, // TODO(FIDL-457): wrong.
+    }));
+
+    END_TEST;
+}
+
+static bool xunions() {
+    BEGIN_TEST;
+
+    TestLibrary test_library(R"FIDL(
+library example;
+
+xunion EmptyXUnion {
+};
+
+xunion XUnionWithOneBool {
+  bool b;
+};
+
+xunion XUnionWithBoundedOutOfLineObject {
+  // smaller than |v| below, so will not be selected for max-out-of-line
+  // calculation.
+  bool b;
+
+  // 1. vector<int32>:5 = 8 bytes for vector element count
+  //                    + 8 bytes for data pointer
+  //                    + 24 bytes out-of-line (20 bytes contents +
+  //                                            4 bytes for 8-byte alignment)
+  //                    = 40 bytes total
+  // 1. vector<vector<int32>:5>:6 = vector of up to six of vector<int32>:5
+  //                              = 8 bytes for vector element count
+  //                              + 8 bytes for data pointer
+  //                              + 240 bytes out-of-line (40 bytes contents * 6)
+  //                              = 256 bytes total
+  vector<vector<int32>:5>:6 v;
+};
+
+xunion XUnionWithUnboundedOutOfLineObject {
+  string s;
+};
+
+struct StructWithOptionalEmptyXUnion {
+  EmptyXUnion? opt_empty;
+};
+
+    )FIDL");
+    ASSERT_TRUE(test_library.Compile());
+
+    auto empty = test_library.LookupXUnion("EmptyXUnion");
+    ASSERT_NONNULL(empty);
+    EXPECT_TRUE(CheckTypeShape(empty->typeshape, Expected {
+        .size = 24,
+        .alignment = 8,
+        .max_out_of_line = 0,
+        .depth = 0, // TODO(FIDL-457): wrong.
+    }));
+
+    auto one_bool = test_library.LookupXUnion("XUnionWithOneBool");
+    ASSERT_NONNULL(one_bool);
+    EXPECT_TRUE(CheckTypeShape(one_bool->typeshape, Expected {
+        .size = 24,
+        .alignment = 8,
+        .max_out_of_line = 8,
+        .depth = 1, // TODO(FIDL-457): wrong.
+    }));
+
+    auto xu = test_library.LookupXUnion("XUnionWithBoundedOutOfLineObject");
+    ASSERT_NONNULL(xu);
+    EXPECT_TRUE(CheckTypeShape(xu->typeshape, Expected {
+        .size = 24,
+        .alignment = 8,
+        .max_out_of_line = 256,
+        .depth = 4, // TODO(FIDL-457): wrong.
+    }));
+
+    auto unbounded = test_library.LookupXUnion("XUnionWithUnboundedOutOfLineObject");
+    ASSERT_NONNULL(unbounded);
+    EXPECT_TRUE(CheckTypeShape(unbounded->typeshape, Expected {
+        .size = 24,
+        .alignment = 8,
+        .max_out_of_line = std::numeric_limits<uint32_t>::max(),
+        .depth = 2, // TODO(FIDL-457): wrong.
+    }));
+
+    auto opt_empty = test_library.LookupStruct("StructWithOptionalEmptyXUnion");
+    ASSERT_NONNULL(opt_empty);
+    EXPECT_TRUE(CheckTypeShape(opt_empty->typeshape, Expected {
+        .size = 24,
+        .alignment = 8,
+        .max_out_of_line = 0,
+        .depth = 0, // TODO(FIDL-457): wrong.
+    }));
+
+    END_TEST;
+}
+
+bool protocols_and_request_of_protocols() {
+    BEGIN_TEST;
+
+    TestLibrary test_library(R"FIDL(
+library example;
+
+protocol SomeProtocol {};
+
+struct UsingSomeProtocol {
+  SomeProtocol value;
+};
+
+struct UsingOptSomeProtocol {
+  SomeProtocol? value;
+};
+
+struct UsingRequestSomeProtocol {
+  request<SomeProtocol> value;
+};
+
+struct UsingOptRequestSomeProtocol {
+  request<SomeProtocol>? value;
+};
+
+    )FIDL");
+    ASSERT_TRUE(test_library.Compile());
+
+    auto using_some_protocol = test_library.LookupStruct("UsingSomeProtocol");
+    ASSERT_NONNULL(using_some_protocol);
+    EXPECT_TRUE(CheckTypeShape(using_some_protocol->typeshape, Expected {
+        .size = 4,
+        .alignment = 4,
+        .max_handles = 1,
+    }));
+
+    auto using_opt_some_protocol = test_library.LookupStruct("UsingOptSomeProtocol");
+    ASSERT_NONNULL(using_opt_some_protocol);
+    EXPECT_TRUE(CheckTypeShape(using_opt_some_protocol->typeshape, Expected {
+        .size = 4,
+        .alignment = 4,
+        .max_handles = 1,
+    }));
+
+    auto using_request_some_protocol = test_library.LookupStruct("UsingRequestSomeProtocol");
+    ASSERT_NONNULL(using_request_some_protocol);
+    EXPECT_TRUE(CheckTypeShape(using_request_some_protocol->typeshape, Expected {
+        .size = 4,
+        .alignment = 4,
+        .max_handles = 1,
+    }));
+
+    auto using_opt_request_some_protocol = test_library.LookupStruct("UsingOptRequestSomeProtocol");
+    ASSERT_NONNULL(using_opt_request_some_protocol);
+    EXPECT_TRUE(CheckTypeShape(using_opt_request_some_protocol->typeshape, Expected {
+        .size = 4,
+        .alignment = 4,
+        .max_handles = 1,
+    }));
+
+    END_TEST;
+}
+
+bool external_definitions() {
+    BEGIN_TEST;
+
+    auto test_library = TestLibrary();
+    test_library.AddSource("main.fidl", R"FIDL(
+library example;
+
+struct ExternalArrayStruct {
+    array<ExternalSimpleStruct>:EXTERNAL_SIZE_DEF a;
+};
+
+struct ExternalStringSizeStruct {
+    string:EXTERNAL_SIZE_DEF a;
+};
+
+struct ExternalVectorSizeStruct {
+    vector<handle>:EXTERNAL_SIZE_DEF a;
+};
+
+    )FIDL");
+    test_library.AddSource("extern_defs.fidl", R"FIDL(
+library example;
+
+const uint32 EXTERNAL_SIZE_DEF = ANOTHER_INDIRECTION;
+const uint32 ANOTHER_INDIRECTION = 32;
+
+struct ExternalSimpleStruct {
+    uint32 a;
+};
+
+    )FIDL");
+    ASSERT_TRUE(test_library.Compile());
+
+    auto ext_struct = test_library.LookupStruct("ExternalSimpleStruct");
+    ASSERT_NONNULL(ext_struct);
+    EXPECT_TRUE(CheckTypeShape(ext_struct->typeshape, Expected {
+        .size = 4,
+        .alignment = 4,
+    }));
+
+    auto ext_arr_struct = test_library.LookupStruct("ExternalArrayStruct");
+    ASSERT_NONNULL(ext_arr_struct);
+    EXPECT_TRUE(CheckTypeShape(ext_arr_struct->typeshape, Expected {
+        .size = 4 * 32,
+        .alignment = 4,
+    }));
+
+    auto ext_str_struct = test_library.LookupStruct("ExternalStringSizeStruct");
+    ASSERT_NONNULL(ext_str_struct);
+    EXPECT_TRUE(CheckTypeShape(ext_str_struct->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 32,
+        .depth = 1,
+    }));
+
+    auto ext_vec_struct = test_library.LookupStruct("ExternalVectorSizeStruct");
+    ASSERT_NONNULL(ext_vec_struct);
+    EXPECT_TRUE(CheckTypeShape(ext_vec_struct->typeshape, Expected {
+        .size = 16,
+        .alignment = 8,
+        .max_out_of_line = 32 * 4,
+        .max_handles = 32,
+        .depth = 1,
+    }));
+
+    END_TEST;
+}
+
+bool recursive_request() {
+  BEGIN_TEST;
+
+  TestLibrary library(R"FIDL(
+library example;
+
+struct WebMessage {
+  request<MessagePort> message_port_req;
+};
+
+protocol MessagePort {
+  PostMessage(WebMessage message) -> (bool success);
+};
+)FIDL");
+  ASSERT_TRUE(library.Compile());
+
+  auto web_message = library.LookupStruct("WebMessage");
+  ASSERT_NONNULL(web_message);
+  EXPECT_TRUE(CheckTypeShape(web_message->typeshape, Expected {
+      .size = 4,
+      .alignment = 4,
+      .max_handles = 1,
+  }));
+
+  auto message_port = library.LookupInterface("MessagePort");
+  ASSERT_NONNULL(message_port);
+  ASSERT_EQ(message_port->methods.size(), 1);
+  auto& post_message = message_port->methods[0];
+  auto post_message_request = post_message.maybe_request;
+  ASSERT_NONNULL(post_message_request);
+  EXPECT_TRUE(CheckTypeShape(post_message_request->typeshape, Expected {
+      .size = 24,
+      .alignment = 8,
+      .max_handles = 1,
+  }));
+
+  END_TEST;
+}
+
+bool recursive_opt_request() {
+  BEGIN_TEST;
+
+  TestLibrary library(R"FIDL(
+library example;
+
+struct WebMessage {
+  request<MessagePort>? opt_message_port_req;
+};
+
+protocol MessagePort {
+  PostMessage(WebMessage message) -> (bool success);
+};
+)FIDL");
+  ASSERT_TRUE(library.Compile());
+
+  auto web_message = library.LookupStruct("WebMessage");
+  ASSERT_NONNULL(web_message);
+  EXPECT_TRUE(CheckTypeShape(web_message->typeshape, Expected {
+      .size = 4,
+      .alignment = 4,
+      .max_handles = 1,
+  }));
+
+  auto message_port = library.LookupInterface("MessagePort");
+  ASSERT_NONNULL(message_port);
+  ASSERT_EQ(message_port->methods.size(), 1);
+  auto& post_message = message_port->methods[0];
+  auto post_message_request = post_message.maybe_request;
+  ASSERT_NONNULL(post_message_request);
+  EXPECT_TRUE(CheckTypeShape(post_message_request->typeshape, Expected {
+      .size = 24,
+      .alignment = 8,
+      .max_handles = 1,
+  }));
+
+  END_TEST;
+}
+
+bool recursive_protocol() {
+  BEGIN_TEST;
+
+  TestLibrary library(R"FIDL(
+library example;
+
+struct WebMessage {
+  MessagePort message_port;
+};
+
+protocol MessagePort {
+  PostMessage(WebMessage message) -> (bool success);
+};
+)FIDL");
+  ASSERT_TRUE(library.Compile());
+
+  auto web_message = library.LookupStruct("WebMessage");
+  ASSERT_NONNULL(web_message);
+  EXPECT_TRUE(CheckTypeShape(web_message->typeshape, Expected {
+      .size = 4,
+      .alignment = 4,
+      .max_handles = 1,
+  }));
+
+  auto message_port = library.LookupInterface("MessagePort");
+  ASSERT_NONNULL(message_port);
+  ASSERT_EQ(message_port->methods.size(), 1);
+  auto& post_message = message_port->methods[0];
+  auto post_message_request = post_message.maybe_request;
+  ASSERT_NONNULL(post_message_request);
+  EXPECT_TRUE(CheckTypeShape(post_message_request->typeshape, Expected {
+      .size = 24,
+      .alignment = 8,
+      .max_handles = 1,
+  }));
+
+  END_TEST;
+}
+
+bool recursive_opt_protocol() {
+  BEGIN_TEST;
+
+  TestLibrary library(R"FIDL(
+library example;
+
+struct WebMessage {
+  MessagePort? opt_message_port;
+};
+
+protocol MessagePort {
+  PostMessage(WebMessage message) -> (bool success);
+};
+)FIDL");
+  ASSERT_TRUE(library.Compile());
+
+  auto web_message = library.LookupStruct("WebMessage");
+  ASSERT_NONNULL(web_message);
+  EXPECT_TRUE(CheckTypeShape(web_message->typeshape, Expected {
+      .size = 4,
+      .alignment = 4,
+      .max_handles = 1,
+  }));
+
+  auto message_port = library.LookupInterface("MessagePort");
+  ASSERT_NONNULL(message_port);
+  ASSERT_EQ(message_port->methods.size(), 1);
+  auto& post_message = message_port->methods[0];
+  auto post_message_request = post_message.maybe_request;
+  ASSERT_NONNULL(post_message_request);
+  EXPECT_TRUE(CheckTypeShape(post_message_request->typeshape, Expected {
+      .size = 24,
+      .alignment = 8,
+      .max_handles = 1,
+  }));
+
+  END_TEST;
+}
+
+bool recursive_struct() {
+  BEGIN_TEST;
+
+  TestLibrary library(R"FIDL(
+library example;
+
+struct TheStruct {
+  TheStruct? opt_one_more;
+};
+)FIDL");
+  ASSERT_TRUE(library.Compile());
+
+  auto the_struct = library.LookupStruct("TheStruct");
+  ASSERT_NONNULL(the_struct);
+  EXPECT_TRUE(CheckTypeShape(the_struct->typeshape, Expected {
+      .size = 8,
+      .alignment = 8,
+      // TODO(FIDL-457): Imprecision here, max out-of-line should be infinite.
+      .max_out_of_line = 0,
+      // TODO(FIDL-457): Incorrectly saturating, there are no handles here.
+      .max_handles = std::numeric_limits<uint32_t>::max(),
+      .depth = std::numeric_limits<uint32_t>::max(),
+  }));
+
+  END_TEST;
+}
+
+bool recursive_struct_with_handles() {
+  BEGIN_TEST;
+
+  TestLibrary library(R"FIDL(
+library example;
+
+struct TheStruct {
+  handle<vmo> some_handle;
+  TheStruct? opt_one_more;
+};
+)FIDL");
+  ASSERT_TRUE(library.Compile());
+
+  auto the_struct = library.LookupStruct("TheStruct");
+  ASSERT_NONNULL(the_struct);
+  EXPECT_TRUE(CheckTypeShape(the_struct->typeshape, Expected {
+      .size = 16,
+      .alignment = 8,
+      // TODO(FIDL-457): Imprecision here, max out-of-line should be infinite.
+      .max_out_of_line = 0,
+      .max_handles = std::numeric_limits<uint32_t>::max(),
+      .depth = std::numeric_limits<uint32_t>::max(),
+  }));
+
+  END_TEST;
+}
+
+bool co_recursive_struct() {
+  BEGIN_TEST;
+
+  TestLibrary library(R"FIDL(
+library example;
+
+struct A {
+    B? foo;
+};
+
+struct B {
+    A? bar;
+};
+)FIDL");
+  ASSERT_TRUE(library.Compile());
+
+  auto struct_a = library.LookupStruct("A");
+  ASSERT_NONNULL(struct_a);
+  EXPECT_TRUE(CheckTypeShape(struct_a->typeshape, Expected {
+      .size = 8,
+      .alignment = 8,
+      // TODO(FIDL-457): Imprecision here, max out-of-line should be infinite.
+      .max_out_of_line = 16,
+      // TODO(FIDL-457): Incorrectly saturating, there are no handles here.
+      .max_handles = std::numeric_limits<uint32_t>::max(),
+      .depth = std::numeric_limits<uint32_t>::max(),
+  }));
+
+  auto struct_b = library.LookupStruct("B");
+  ASSERT_NONNULL(struct_b);
+  EXPECT_TRUE(CheckTypeShape(struct_b->typeshape, Expected {
+      .size = 8,
+      .alignment = 8,
+      // TODO(FIDL-457): Imprecision here, max out-of-line should be infinite.
+      .max_out_of_line = 8,
+      // TODO(FIDL-457): Incorrectly saturating, there are no handles here.
+      .max_handles = std::numeric_limits<uint32_t>::max(),
+      .depth = std::numeric_limits<uint32_t>::max(),
+  }));
+
+  END_TEST;
+}
+
+bool co_recursive_struct_with_handles() {
+  BEGIN_TEST;
+
+  TestLibrary library(R"FIDL(
+library example;
+
+struct A {
+    handle a;
+    B? foo;
+};
+
+struct B {
+    handle b;
+    A? bar;
+};
+)FIDL");
+  ASSERT_TRUE(library.Compile());
+
+  auto struct_a = library.LookupStruct("A");
+  ASSERT_NONNULL(struct_a);
+  EXPECT_TRUE(CheckTypeShape(struct_a->typeshape, Expected {
+      .size = 16,
+      .alignment = 8,
+      // TODO(FIDL-457): Imprecision here, max out-of-line should be infinite.
+      .max_out_of_line = 32,
+      .max_handles = std::numeric_limits<uint32_t>::max(),
+      .depth = std::numeric_limits<uint32_t>::max(),
+  }));
+
+  auto struct_b = library.LookupStruct("B");
+  ASSERT_NONNULL(struct_b);
+  EXPECT_TRUE(CheckTypeShape(struct_b->typeshape, Expected {
+      .size = 16,
+      .alignment = 8,
+      // TODO(FIDL-457): Imprecision here, max out-of-line should be infinite.
+      .max_out_of_line = 16,
+      .max_handles = std::numeric_limits<uint32_t>::max(),
+      .depth = std::numeric_limits<uint32_t>::max(),
+  }));
+
+  END_TEST;
+}
+
+bool co_recursive_struct2() {
+  BEGIN_TEST;
+
+  TestLibrary library(R"FIDL(
+library example;
+
+struct Foo {
+    Bar b;
+};
+
+struct Bar {
+    Foo? f;
+};
+)FIDL");
+  ASSERT_TRUE(library.Compile());
+
+  auto struct_foo = library.LookupStruct("Foo");
+  ASSERT_NONNULL(struct_foo);
+  EXPECT_TRUE(CheckTypeShape(struct_foo->typeshape, Expected {
+      .size = 8,
+      .alignment = 8,
+      // TODO(FIDL-457): Imprecision here, max out-of-line should be infinite.
+      .max_out_of_line = 0,
+      // TODO(FIDL-457): Incorrectly saturating, there are no handles here.
+      .max_handles = std::numeric_limits<uint32_t>::max(),
+      .depth = std::numeric_limits<uint32_t>::max(),
+  }));
+
+  auto struct_bar = library.LookupStruct("Bar");
+  ASSERT_NONNULL(struct_bar);
+  EXPECT_TRUE(CheckTypeShape(struct_bar->typeshape, Expected {
+      .size = 8,
+      .alignment = 8,
+      // TODO(FIDL-457): Imprecision here, max out-of-line should be infinite.
+      .max_out_of_line = 0,
+      // TODO(FIDL-457): Incorrectly saturating, there are no handles here.
+      .max_handles = std::numeric_limits<uint32_t>::max(),
+      .depth = std::numeric_limits<uint32_t>::max(),
+  }));
+
+  END_TEST;
+}
+
+bool struct_two_deep() {
+  BEGIN_TEST;
+
+  TestLibrary library(R"FIDL(
+library example;
+
+struct DiffEntry {
+    vector<uint8>:256 key;
+
+    Value? base;
+    Value? left;
+    Value? right;
+};
+
+struct Value {
+    Buffer? value;
+    Priority priority;
+};
+
+struct Buffer {
+    handle<vmo> vmo;
+    uint64 size;
+};
+
+enum Priority {
+    EAGER = 0;
+    LAZY = 1;
+};
+)FIDL");
+  ASSERT_TRUE(library.Compile());
+
+  auto buffer = library.LookupStruct("Buffer");
+  ASSERT_NONNULL(buffer);
+  EXPECT_TRUE(CheckTypeShape(buffer->typeshape, Expected {
+      .size = 16,
+      .alignment = 8,
+      .max_handles = 1,
+  }));
+
+  auto value = library.LookupStruct("Value");
+  ASSERT_NONNULL(value);
+  EXPECT_TRUE(CheckTypeShape(value->typeshape, Expected {
+      .size = 16,
+      .alignment = 8,
+      .max_out_of_line = 16,
+      .max_handles = 1,
+      .depth = 1,
+  }));
+
+  auto diff_entry = library.LookupStruct("DiffEntry");
+  ASSERT_NONNULL(diff_entry);
+  EXPECT_TRUE(CheckTypeShape(diff_entry->typeshape, Expected {
+      .size = 40,
+      .alignment = 8,
+      .max_out_of_line = 352,
+      .max_handles = 3,
+      .depth = 2,
+  }));
+
+  END_TEST;
+}
+
+bool protocol_child_and_parent() {
+  BEGIN_TEST;
+
+  SharedAmongstLibraries shared;
+  TestLibrary parent_library("parent.fidl", R"FIDL(
+library parent;
+
+[FragileBase]
+protocol Parent {
+  Sync() -> ();
+};
+)FIDL", &shared);
+  ASSERT_TRUE(parent_library.Compile());
+
+  TestLibrary child_library("child.fidl", R"FIDL(
+library child;
+
+using parent;
+
+protocol Child {
+  compose parent.Parent;
+};
+)FIDL", &shared);
+  ASSERT_TRUE(child_library.AddDependentLibrary(std::move(parent_library)));
+  ASSERT_TRUE(child_library.Compile());
+
+  auto child = child_library.LookupInterface("Child");
+  ASSERT_NONNULL(child);
+  ASSERT_EQ(child->all_methods.size(), 1);
+  auto& sync = child->all_methods[0];
+  auto sync_request = sync->maybe_request;
+  ASSERT_NONNULL(sync_request);
+  EXPECT_TRUE(CheckTypeShape(sync_request->typeshape, Expected {
+      .size = 16,
+      .alignment = 8,
+  }));
+
+  END_TEST;
+}
+
+} // namespace
+
+BEGIN_TEST_CASE(typeshape_tests)
+RUN_TEST(simple_structs)
+RUN_TEST(simple_structs_with_handles)
+RUN_TEST(simple_tables)
+RUN_TEST(simple_tables_with_handles)
+RUN_TEST(optional_structs)
+RUN_TEST(optional_tables)
+RUN_TEST(unions)
+RUN_TEST(unions_with_handles)
+RUN_TEST(vectors)
+RUN_TEST(vectors_with_handles)
+RUN_TEST(strings)
+RUN_TEST(arrays)
+RUN_TEST(arrays_with_handles)
+RUN_TEST(xunions)
+// RUN_TEST(xunions_with_handles) TODO(pascallouis)
+RUN_TEST(protocols_and_request_of_protocols)
+RUN_TEST(external_definitions)
+RUN_TEST(recursive_request)
+RUN_TEST(recursive_opt_request)
+RUN_TEST(recursive_protocol)
+RUN_TEST(recursive_opt_protocol)
+RUN_TEST(recursive_struct)
+RUN_TEST(recursive_struct_with_handles)
+RUN_TEST(co_recursive_struct)
+RUN_TEST(co_recursive_struct_with_handles)
+RUN_TEST(co_recursive_struct2)
+RUN_TEST(struct_two_deep)
+RUN_TEST(protocol_child_and_parent)
+END_TEST_CASE(typeshape_tests)
diff --git a/zircon/system/utest/fidl-compiler/using_tests.cpp b/zircon/system/utest/fidl-compiler/using_tests.cpp
index 98cd554..a421e83 100644
--- a/zircon/system/utest/fidl-compiler/using_tests.cpp
+++ b/zircon/system/utest/fidl-compiler/using_tests.cpp
@@ -39,7 +39,7 @@
 
 )FIDL", &shared);
     ASSERT_TRUE(library.AddDependentLibrary(std::move(dependency)));
-    EXPECT_TRUE(library.Compile());
+    ASSERT_TRUE(library.Compile());
 
     END_TEST;
 }
diff --git a/zircon/system/utest/fidl-compiler/visitor_unittests.cpp b/zircon/system/utest/fidl-compiler/visitor_unittests.cpp
index 10162f6..5178660 100644
--- a/zircon/system/utest/fidl-compiler/visitor_unittests.cpp
+++ b/zircon/system/utest/fidl-compiler/visitor_unittests.cpp
@@ -85,7 +85,7 @@
     for (auto element : Examples::map()) {
         TestLibrary library(element.first, element.second);
         std::unique_ptr<fidl::raw::File> ast;
-        EXPECT_TRUE(library.Parse(ast));
+        EXPECT_TRUE(library.Parse(&ast));
 
         NoopTreeVisitor visitor;
         visitor.OnFile(ast);