diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 4477dee..24a157d 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -25,7 +25,7 @@
         id: automatic_release
         uses: 'marvinpinto/action-automatic-releases@latest'
         with:
-          repo_token: '${{ secrets.GITHUB_TOKEN }}'
+          repo_token: '${{ secrets.RELEASE_PAT }}'
           automatic_release_tag: ${{ steps.set_release_version.outputs.version }}
           prerelease: false
           title: ${{ steps.set_release_version.outputs.version }}
diff --git a/.github/workflows/verify-pull-request.yml b/.github/workflows/verify-pull-request.yml
index da4ea56..744b5c9 100644
--- a/.github/workflows/verify-pull-request.yml
+++ b/.github/workflows/verify-pull-request.yml
@@ -8,6 +8,7 @@
     strategy:
       matrix:
         cpp-compiler: ["clang", "gcc"]
+        options: ["-c opt", ""]
     steps:
       - uses: actions/checkout@v4
       - uses: bazel-contrib/setup-bazel@0.8.5
@@ -16,7 +17,7 @@
           disk-cache: "verify-pr:run-bazel-tests:${{ matrix.cpp-compiler }}"
           repository-cache: true
       - run: echo "CC=${{ matrix.cpp-compiler }}" >> $GITHUB_ENV
-      - run: bazel test ...
+      - run: bazel test --test_output=errors ${{ matrix.options }} ...
   check-formatting:
     name: "Check Python formatting"
     runs-on: ubuntu-latest
@@ -26,3 +27,14 @@
         with:
           options: "--check --verbose"
           version: "24.8.0"
+  check-build-json:
+    name: "Check build.json"
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+      - uses: bazel-contrib/setup-bazel@0.8.5
+        with:
+          bazelisk-cache: true
+          disk-cache: "verify-pr:check-build-json"
+          repository-cache: true
+      - run: python3 scripts/build_helpers/manage_build_json.py --validate
diff --git a/build.json b/build.json
new file mode 100644
index 0000000..4576ad1
--- /dev/null
+++ b/build.json
@@ -0,0 +1,68 @@
+{
+  // A list of all source files required to build the Emboss compiler.
+  "embossc_sources": [
+    "compiler/__init__.py",
+    "compiler/back_end/__init__.py",
+    "compiler/back_end/cpp/__init__.py",
+    "compiler/back_end/cpp/attributes.py",
+    "compiler/back_end/cpp/emboss_codegen_cpp.py",
+    "compiler/back_end/cpp/generated_code_templates",
+    "compiler/back_end/cpp/header_generator.py",
+    "compiler/back_end/util/__init__.py",
+    "compiler/back_end/util/code_template.py",
+    "compiler/front_end/__init__.py",
+    "compiler/front_end/attribute_checker.py",
+    "compiler/front_end/attributes.py",
+    "compiler/front_end/constraints.py",
+    "compiler/front_end/dependency_checker.py",
+    "compiler/front_end/emboss_front_end.py",
+    "compiler/front_end/error_examples",
+    "compiler/front_end/expression_bounds.py",
+    "compiler/front_end/generated/cached_parser.py",
+    "compiler/front_end/glue.py",
+    "compiler/front_end/lr1.py",
+    "compiler/front_end/make_parser.py",
+    "compiler/front_end/module_ir.py",
+    "compiler/front_end/parser.py",
+    "compiler/front_end/prelude.emb",
+    "compiler/front_end/reserved_words",
+    "compiler/front_end/symbol_resolver.py",
+    "compiler/front_end/synthetics.py",
+    "compiler/front_end/tokenizer.py",
+    "compiler/front_end/type_check.py",
+    "compiler/front_end/write_inference.py",
+    "compiler/util/__init__.py",
+    "compiler/util/attribute_util.py",
+    "compiler/util/error.py",
+    "compiler/util/expression_parser.py",
+    "compiler/util/ir_data.py",
+    "compiler/util/ir_data_fields.py",
+    "compiler/util/ir_data_utils.py",
+    "compiler/util/ir_util.py",
+    "compiler/util/name_conversion.py",
+    "compiler/util/parser_types.py",
+    "compiler/util/parser_util.py",
+    "compiler/util/resources.py",
+    "compiler/util/simple_memoizer.py",
+    "compiler/util/traverse_ir.py",
+    "embossc"
+  ],
+  // A list of all source files required for the Emboss C++ runtime.
+  "emboss_runtime_cpp_sources": [
+    "runtime/cpp/emboss_arithmetic.h",
+    "runtime/cpp/emboss_arithmetic_all_known_generated.h",
+    "runtime/cpp/emboss_arithmetic_maximum_operation_generated.h",
+    "runtime/cpp/emboss_array_view.h",
+    "runtime/cpp/emboss_bit_util.h",
+    "runtime/cpp/emboss_constant_view.h",
+    "runtime/cpp/emboss_cpp_types.h",
+    "runtime/cpp/emboss_cpp_util.h",
+    "runtime/cpp/emboss_defines.h",
+    "runtime/cpp/emboss_enum_view.h",
+    "runtime/cpp/emboss_maybe.h",
+    "runtime/cpp/emboss_memory_util.h",
+    "runtime/cpp/emboss_prelude.h",
+    "runtime/cpp/emboss_text_util.h",
+    "runtime/cpp/emboss_view_parameters.h"
+  ]
+}
diff --git a/compiler/back_end/cpp/BUILD b/compiler/back_end/cpp/BUILD
index 5bac536..14eac6a 100644
--- a/compiler/back_end/cpp/BUILD
+++ b/compiler/back_end/cpp/BUILD
@@ -16,8 +16,7 @@
 
 load("@rules_python//python:py_binary.bzl", "py_binary")
 load("@rules_python//python:py_library.bzl", "py_library")
-load("@rules_python//python:py_test.bzl", "py_test")
-load(":build_defs.bzl", "emboss_cc_test")
+load(":build_defs.bzl", "cpp_golden_test", "emboss_cc_test")
 
 package(
     default_visibility = [
@@ -388,3 +387,213 @@
         "@com_google_googletest//:gtest_main",
     ],
 )
+
+# New golden test infrastructure
+py_library(
+    name = "one_golden_test_lib",
+    srcs = ["one_golden_test.py"],
+)
+
+py_binary(
+    name = "run_one_golden_test",
+    srcs = ["run_one_golden_test.py"],
+    deps = [":one_golden_test_lib"],
+)
+
+cpp_golden_test(
+    name = "anonymous_bits_golden_test",
+    emb_file = "//testdata:anonymous_bits.emb",
+    golden_file = "//testdata/golden_cpp:anonymous_bits.emb.h",
+)
+
+cpp_golden_test(
+    name = "bits_golden_test",
+    emb_file = "//testdata:bits.emb",
+    golden_file = "//testdata/golden_cpp:bits.emb.h",
+)
+
+cpp_golden_test(
+    name = "absolute_cpp_namespace_golden_test",
+    emb_file = "//testdata:absolute_cpp_namespace.emb",
+    golden_file = "//testdata/golden_cpp:absolute_cpp_namespace.emb.h",
+)
+
+cpp_golden_test(
+    name = "alignments_golden_test",
+    emb_file = "//testdata:alignments.emb",
+    golden_file = "//testdata/golden_cpp:alignments.emb.h",
+)
+
+cpp_golden_test(
+    name = "auto_array_size_golden_test",
+    emb_file = "//testdata:auto_array_size.emb",
+    golden_file = "//testdata/golden_cpp:auto_array_size.emb.h",
+)
+
+cpp_golden_test(
+    name = "bcd_golden_test",
+    emb_file = "//testdata:bcd.emb",
+    golden_file = "//testdata/golden_cpp:bcd.emb.h",
+)
+
+cpp_golden_test(
+    name = "complex_offset_golden_test",
+    emb_file = "//testdata:complex_offset.emb",
+    golden_file = "//testdata/golden_cpp:complex_offset.emb.h",
+)
+
+cpp_golden_test(
+    name = "complex_structure_golden_test",
+    emb_file = "//testdata:complex_structure.emb",
+    golden_file = "//testdata/golden_cpp:complex_structure.emb.h",
+)
+
+cpp_golden_test(
+    name = "condition_golden_test",
+    emb_file = "//testdata:condition.emb",
+    golden_file = "//testdata/golden_cpp:condition.emb.h",
+)
+
+cpp_golden_test(
+    name = "cpp_namespace_golden_test",
+    emb_file = "//testdata:cpp_namespace.emb",
+    golden_file = "//testdata/golden_cpp:cpp_namespace.emb.h",
+)
+
+cpp_golden_test(
+    name = "dynamic_size_golden_test",
+    emb_file = "//testdata:dynamic_size.emb",
+    golden_file = "//testdata/golden_cpp:dynamic_size.emb.h",
+)
+
+cpp_golden_test(
+    name = "enum_case_golden_test",
+    emb_file = "//testdata:enum_case.emb",
+    golden_file = "//testdata/golden_cpp:enum_case.emb.h",
+)
+
+cpp_golden_test(
+    name = "enum_golden_test",
+    emb_file = "//testdata:enum.emb",
+    golden_file = "//testdata/golden_cpp:enum.emb.h",
+)
+
+cpp_golden_test(
+    name = "explicit_sizes_golden_test",
+    emb_file = "//testdata:explicit_sizes.emb",
+    golden_file = "//testdata/golden_cpp:explicit_sizes.emb.h",
+)
+
+cpp_golden_test(
+    name = "float_golden_test",
+    emb_file = "//testdata:float.emb",
+    golden_file = "//testdata/golden_cpp:float.emb.h",
+)
+
+cpp_golden_test(
+    name = "imported_golden_test",
+    emb_file = "//testdata:imported.emb",
+    golden_file = "//testdata/golden_cpp:imported.emb.h",
+)
+
+cpp_golden_test(
+    name = "inline_type_golden_test",
+    emb_file = "//testdata:inline_type.emb",
+    golden_file = "//testdata/golden_cpp:inline_type.emb.h",
+)
+
+cpp_golden_test(
+    name = "int_sizes_golden_test",
+    emb_file = "//testdata:int_sizes.emb",
+    golden_file = "//testdata/golden_cpp:int_sizes.emb.h",
+)
+
+cpp_golden_test(
+    name = "large_array_golden_test",
+    emb_file = "//testdata:large_array.emb",
+    golden_file = "//testdata/golden_cpp:large_array.emb.h",
+)
+
+cpp_golden_test(
+    name = "nested_structure_golden_test",
+    emb_file = "//testdata:nested_structure.emb",
+    golden_file = "//testdata/golden_cpp:nested_structure.emb.h",
+)
+
+cpp_golden_test(
+    name = "next_keyword_golden_test",
+    emb_file = "//testdata:next_keyword.emb",
+    golden_file = "//testdata/golden_cpp:next_keyword.emb.h",
+)
+
+cpp_golden_test(
+    name = "no_cpp_namespace_golden_test",
+    emb_file = "//testdata:no_cpp_namespace.emb",
+    golden_file = "//testdata/golden_cpp:no_cpp_namespace.emb.h",
+)
+
+cpp_golden_test(
+    name = "no_enum_traits_golden_test",
+    emb_file = "//testdata:no_enum_traits.emb",
+    golden_file = "//testdata/golden_cpp:no_enum_traits.emb.h",
+)
+
+cpp_golden_test(
+    name = "parameters_golden_test",
+    emb_file = "//testdata:parameters.emb",
+    golden_file = "//testdata/golden_cpp:parameters.emb.h",
+)
+
+cpp_golden_test(
+    name = "requires_golden_test",
+    emb_file = "//testdata:requires.emb",
+    golden_file = "//testdata/golden_cpp:requires.emb.h",
+)
+
+cpp_golden_test(
+    name = "start_size_range_golden_test",
+    emb_file = "//testdata:start_size_range.emb",
+    golden_file = "//testdata/golden_cpp:start_size_range.emb.h",
+)
+
+cpp_golden_test(
+    name = "subtypes_golden_test",
+    emb_file = "//testdata:subtypes.emb",
+    golden_file = "//testdata/golden_cpp:subtypes.emb.h",
+)
+
+cpp_golden_test(
+    name = "text_format_golden_test",
+    emb_file = "//testdata:text_format.emb",
+    golden_file = "//testdata/golden_cpp:text_format.emb.h",
+)
+
+cpp_golden_test(
+    name = "uint_sizes_golden_test",
+    emb_file = "//testdata:uint_sizes.emb",
+    golden_file = "//testdata/golden_cpp:uint_sizes.emb.h",
+)
+
+cpp_golden_test(
+    name = "virtual_field_golden_test",
+    emb_file = "//testdata:virtual_field.emb",
+    golden_file = "//testdata/golden_cpp:virtual_field.emb.h",
+)
+
+cpp_golden_test(
+    name = "importer_golden_test",
+    emb_file = "//testdata:importer.emb",
+    golden_file = "//testdata/golden_cpp:importer.emb.h",
+)
+
+cpp_golden_test(
+    name = "importer2_golden_test",
+    emb_file = "//testdata:importer2.emb",
+    golden_file = "//testdata/golden_cpp:importer2.emb.h",
+)
+
+cpp_golden_test(
+    name = "imported_genfiles_golden_test",
+    emb_file = "//testdata:imported_genfiles.emb",
+    golden_file = "//testdata/golden_cpp:imported_genfiles.emb.h",
+)
diff --git a/compiler/back_end/cpp/build_defs.bzl b/compiler/back_end/cpp/build_defs.bzl
index a1df7aa..78d22f3 100644
--- a/compiler/back_end/cpp/build_defs.bzl
+++ b/compiler/back_end/cpp/build_defs.bzl
@@ -16,18 +16,62 @@
 # vim:set ft=blazebuild:
 """Rule to generate cc_tests with and without system-specific optimizations."""
 
+load("@rules_python//python:py_test.bzl", "py_test")
+
 def emboss_cc_test(name, copts = None, no_w_sign_compare = False, **kwargs):
     """Generates cc_test rules with and without -DEMBOSS_NO_OPTIMIZATIONS."""
     native.cc_test(
         name = name,
-        copts = ["-DEMBOSS_FORCE_ALL_CHECKS"] + (copts or []),
+        copts = copts or [],
         **kwargs
     )
     native.cc_test(
         name = name + "_no_opts",
         copts = [
             "-DEMBOSS_NO_OPTIMIZATIONS",
-            "-DEMBOSS_FORCE_ALL_CHECKS",
         ] + ([] if no_w_sign_compare else ["-Wsign-compare"]) + (copts or []),
         **kwargs
     )
+    native.cc_test(
+        name = name + "_no_checks",
+        copts = ["-DEMBOSS_SKIP_CHECKS"] + (copts or []),
+        **kwargs
+    )
+    native.cc_test(
+        name = name + "_no_checks_no_opts",
+        copts = [
+            "-DEMBOSS_NO_OPTIMIZATIONS",
+            "-DEMBOSS_SKIP_CHECKS",
+        ] + ([] if no_w_sign_compare else ["-Wsign-compare"]) + (copts or []),
+        **kwargs
+    )
+
+def cpp_golden_test(name, emb_file, golden_file, import_dirs = []):
+    """Defines a C++ golden file test.
+
+    Args:
+        name: The name of the test.
+        emb_file: The .emb file to test.
+        golden_file: The golden .h file.
+        import_dirs: A list of import directories.
+    """
+    py_test(
+        name = name,
+        main = ":run_one_golden_test.py",
+        srcs = [":run_one_golden_test.py", ":one_golden_test.py"],
+        tags = ["golden"],
+        args = [
+            "$(location //compiler/front_end:emboss_front_end)",
+            "$(location :emboss_codegen_cpp)",
+            "$(location %s)" % emb_file,
+            "$(location %s)" % golden_file,
+        ] + ["--import-dir=" + d for d in import_dirs],
+        data = [
+            "//compiler/front_end:emboss_front_end",
+            ":emboss_codegen_cpp",
+            emb_file,
+            golden_file,
+            "//testdata:test_embs",
+        ] + import_dirs,
+        deps = [":one_golden_test_lib"],
+    )
diff --git a/compiler/back_end/cpp/header_generator.py b/compiler/back_end/cpp/header_generator.py
index 0201d12..5860bc8 100644
--- a/compiler/back_end/cpp/header_generator.py
+++ b/compiler/back_end/cpp/header_generator.py
@@ -418,7 +418,7 @@
     adapted_buffer_type = _get_adapted_cpp_buffer_type_for_field(
         type_definition, size, buffer_type, byte_order, parent_addressable_unit
     )
-    if type_definition.HasField("external"):
+    if type_definition.has_field("external"):
         # Externals do not (yet) support runtime parameters.
         return (
             code_template.format_template(
@@ -433,7 +433,7 @@
             ),
             [],
         )
-    elif type_definition.HasField("structure"):
+    elif type_definition.has_field("structure"):
         parameter_types = []
         for parameter in type_definition.runtime_parameter:
             parameter_types.append(
@@ -450,7 +450,7 @@
             ),
             parameter_types,
         )
-    elif type_definition.HasField("enumeration"):
+    elif type_definition.has_field("enumeration"):
         return (
             code_template.format_template(
                 _TEMPLATES.enum_view_type,
@@ -534,7 +534,7 @@
             element_view_parameters,
         )
     else:
-        assert type_ir.HasField("atomic_type")
+        assert type_ir.has_field("atomic_type")
         reference = type_ir.atomic_type.reference
         referenced_type = ir_util.find_object(reference, ir)
         if parent_addressable_unit > referenced_type.addressable_unit:
@@ -829,13 +829,13 @@
                 True,
             )
     elif expression.type.which_type == "boolean":
-        if expression.type.boolean.HasField("value"):
+        if expression.type.boolean.has_field("value"):
             if expression.type.boolean.value:
                 return _ExpressionResult(_maybe_type("bool") + "(true)", True)
             else:
                 return _ExpressionResult(_maybe_type("bool") + "(false)", True)
     elif expression.type.which_type == "enumeration":
-        if expression.type.enumeration.HasField("value"):
+        if expression.type.enumeration.has_field("value"):
             return _ExpressionResult(
                 _render_enum_value(expression.type.enumeration, ir), True
             )
@@ -889,7 +889,7 @@
 ):
     """Returns the C++ view type for a field."""
     field_size = None
-    if field_ir.type.HasField("size_in_bits"):
+    if field_ir.type.has_field("size_in_bits"):
         field_size = ir_util.constant_value(field_ir.type.size_in_bits)
         assert field_size is not None
     elif ir_util.is_constant(field_ir.location.size):
@@ -1365,7 +1365,7 @@
     units = {1: "Bits", 8: "Bytes"}[type_ir.addressable_unit]
 
     for subtype in type_ir.subtype:
-        if subtype.HasField("enumeration"):
+        if subtype.has_field("enumeration"):
             enum_using_statements.append(
                 code_template.format_template(
                     _TEMPLATES.enum_using_statement,
@@ -1672,11 +1672,11 @@
 
 def _generate_type_definition(type_ir, ir, config: Config):
     """Generates C++ for an Emboss type."""
-    if type_ir.HasField("structure"):
+    if type_ir.has_field("structure"):
         return _generate_structure_definition(type_ir, ir, config)
-    elif type_ir.HasField("enumeration"):
+    elif type_ir.has_field("enumeration"):
         return _generate_enum_definition(type_ir, config.include_enum_traits)
-    elif type_ir.HasField("external"):
+    elif type_ir.has_field("external"):
         # TODO(bolms): This should probably generate an #include.
         return "", "", ""
     else:
@@ -1747,9 +1747,14 @@
         original start column.
     """
 
-    new_location = ir_data_utils.copy(source_location)
-    new_location.start.column = source_location.start.column + offset[0]
-    new_location.end.column = source_location.start.column + offset[1]
+    new_location = source_location._replace(
+        start=source_location.start._replace(
+            column=source_location.start.column + offset[0]
+        ),
+        end=source_location.start._replace(
+            column=source_location.start.column + offset[1]
+        ),
+    )
 
     return new_location
 
diff --git a/compiler/back_end/cpp/header_generator_test.py b/compiler/back_end/cpp/header_generator_test.py
index 6d31df8..d125d9e 100644
--- a/compiler/back_end/cpp/header_generator_test.py
+++ b/compiler/back_end/cpp/header_generator_test.py
@@ -126,12 +126,11 @@
         )
         attr = ir.module[0].type[0].attribute[0]
 
-        bad_case_source_location = ir_data.Location()
-        bad_case_source_location = ir_data_utils.builder(bad_case_source_location)
-        bad_case_source_location.CopyFrom(attr.value.source_location)
-        # Location of SHORTY_CASE in the attribute line.
-        bad_case_source_location.start.column = 30
-        bad_case_source_location.end.column = 41
+        # SourceLocation of SHORTY_CASE in the attribute line.
+        bad_case_source_location = attr.value.source_location._replace(
+            start=attr.value.source_location.start._replace(column=30),
+            end=attr.value.source_location.end._replace(column=41),
+        )
 
         self.assertEqual(
             [
@@ -156,12 +155,11 @@
         )
         attr = ir.module[0].type[0].attribute[0]
 
-        bad_case_source_location = ir_data.Location()
-        bad_case_source_location = ir_data_utils.builder(bad_case_source_location)
-        bad_case_source_location.CopyFrom(attr.value.source_location)
-        # Location of bad_CASE in the attribute line.
-        bad_case_source_location.start.column = 43
-        bad_case_source_location.end.column = 51
+        # SourceLocation of bad_CASE in the attribute line.
+        bad_case_source_location = attr.value.source_location._replace(
+            start=attr.value.source_location.start._replace(column=43),
+            end=attr.value.source_location.end._replace(column=51),
+        )
 
         self.assertEqual(
             [
@@ -186,12 +184,11 @@
         )
         attr = ir.module[0].type[0].attribute[0]
 
-        bad_case_source_location = ir_data.Location()
-        bad_case_source_location = ir_data_utils.builder(bad_case_source_location)
-        bad_case_source_location.CopyFrom(attr.value.source_location)
-        # Location of BAD_case in the attribute line.
-        bad_case_source_location.start.column = 55
-        bad_case_source_location.end.column = 63
+        # SourceLocation of BAD_case in the attribute line.
+        bad_case_source_location = attr.value.source_location._replace(
+            start=attr.value.source_location.start._replace(column=55),
+            end=attr.value.source_location.end._replace(column=63),
+        )
 
         self.assertEqual(
             [
@@ -216,12 +213,11 @@
         )
         attr = ir.module[0].type[0].attribute[0]
 
-        bad_case_source_location = ir_data.Location()
-        bad_case_source_location = ir_data_utils.builder(bad_case_source_location)
-        bad_case_source_location.CopyFrom(attr.value.source_location)
-        # Location of the second SHOUTY_CASE in the attribute line.
-        bad_case_source_location.start.column = 43
-        bad_case_source_location.end.column = 54
+        # SourceLocation of the second SHOUTY_CASE in the attribute line.
+        bad_case_source_location = attr.value.source_location._replace(
+            start=attr.value.source_location.start._replace(column=43),
+            end=attr.value.source_location.end._replace(column=54),
+        )
 
         self.assertEqual(
             [
@@ -246,12 +242,11 @@
         )
         attr = ir.module[0].type[0].attribute[0]
 
-        bad_case_source_location = ir_data.Location()
-        bad_case_source_location = ir_data_utils.builder(bad_case_source_location)
-        bad_case_source_location.CopyFrom(attr.value.source_location)
-        # Location of excess comma.
-        bad_case_source_location.start.column = 42
-        bad_case_source_location.end.column = 42
+        # SourceLocation of excess comma.
+        bad_case_source_location = attr.value.source_location._replace(
+            start=attr.value.source_location.start._replace(column=42),
+            end=attr.value.source_location.end._replace(column=42),
+        )
 
         self.assertEqual(
             [
@@ -274,8 +269,10 @@
             "  BAZ = 2\n"
         )
 
-        bad_case_source_location.start.column = 30
-        bad_case_source_location.end.column = 30
+        bad_case_source_location = attr.value.source_location._replace(
+            start=attr.value.source_location.start._replace(column=30),
+            end=attr.value.source_location.end._replace(column=30),
+        )
 
         self.assertEqual(
             [
@@ -298,8 +295,10 @@
             "  BAZ = 2\n"
         )
 
-        bad_case_source_location.start.column = 54
-        bad_case_source_location.end.column = 54
+        bad_case_source_location = attr.value.source_location._replace(
+            start=attr.value.source_location.start._replace(column=54),
+            end=attr.value.source_location.end._replace(column=54),
+        )
 
         self.assertEqual(
             [
@@ -322,8 +321,10 @@
             "  BAZ = 2\n"
         )
 
-        bad_case_source_location.start.column = 45
-        bad_case_source_location.end.column = 45
+        bad_case_source_location = attr.value.source_location._replace(
+            start=attr.value.source_location.start._replace(column=45),
+            end=attr.value.source_location.end._replace(column=45),
+        )
 
         self.assertEqual(
             [
@@ -346,8 +347,10 @@
             "  BAZ = 2\n"
         )
 
-        bad_case_source_location.start.column = 30
-        bad_case_source_location.end.column = 30
+        bad_case_source_location = attr.value.source_location._replace(
+            start=attr.value.source_location.start._replace(column=30),
+            end=attr.value.source_location.end._replace(column=30),
+        )
 
         self.assertEqual(
             [
@@ -370,8 +373,10 @@
             "  BAZ = 2\n"
         )
 
-        bad_case_source_location.start.column = 35
-        bad_case_source_location.end.column = 35
+        bad_case_source_location = attr.value.source_location._replace(
+            start=attr.value.source_location.start._replace(column=35),
+            end=attr.value.source_location.end._replace(column=35),
+        )
 
         self.assertEqual(
             [
@@ -394,8 +399,10 @@
             "  BAZ = 2\n"
         )
 
-        bad_case_source_location.start.column = 31
-        bad_case_source_location.end.column = 31
+        bad_case_source_location = attr.value.source_location._replace(
+            start=attr.value.source_location.start._replace(column=31),
+            end=attr.value.source_location.end._replace(column=31),
+        )
 
         self.assertEqual(
             [
diff --git a/compiler/back_end/cpp/one_golden_test.py b/compiler/back_end/cpp/one_golden_test.py
new file mode 100644
index 0000000..196e4a2
--- /dev/null
+++ b/compiler/back_end/cpp/one_golden_test.py
@@ -0,0 +1,95 @@
+# Copyright 2025 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import difflib
+import os
+import subprocess
+import sys
+import unittest
+
+
+class OneGoldenTest(unittest.TestCase):
+    def __init__(
+        self,
+        emboss_front_end,
+        emboss_compiler,
+        emb_file,
+        golden_file,
+        include_dirs=None,
+    ):
+        super(OneGoldenTest, self).__init__("test_golden_file")
+        self.emboss_front_end = emboss_front_end
+        self.emboss_compiler = emboss_compiler
+        self.emb_file = emb_file
+        self.golden_file = golden_file
+        self.include_dirs = include_dirs if include_dirs is not None else []
+
+    def test_golden_file(self):
+        temp_dir = os.environ.get("TEST_TMPDIR", "")
+        ir_path = os.path.join(temp_dir, "ir.json")
+        output_path = os.path.join(temp_dir, os.path.basename(self.golden_file))
+
+        front_end_args = [
+            self.emboss_front_end,
+            self.emb_file,
+            "--output-file",
+            ir_path,
+        ]
+        for include_dir in self.include_dirs:
+            front_end_args.extend(["--import-dir", include_dir])
+
+        process = subprocess.run(front_end_args, capture_output=True, text=True)
+        self.assertEqual(
+            process.returncode, 0, f"Front end failed with error:\n{process.stderr}"
+        )
+
+        compiler_args = [
+            self.emboss_compiler,
+            "--input-file",
+            ir_path,
+            "--output-file",
+            output_path,
+        ]
+
+        process = subprocess.run(compiler_args, capture_output=True, text=True)
+
+        self.assertEqual(
+            process.returncode, 0, f"Compiler failed with error:\n{process.stderr}"
+        )
+
+        with open(output_path, "r") as f:
+            generated_contents = f.read()
+
+        with open(self.golden_file, "r") as f:
+            golden_contents = f.read()
+
+        self.assertMultiLineEqual(
+            golden_contents,
+            generated_contents,
+            msg="Generated file does not match golden file. Diff:\n"
+            + "".join(
+                difflib.unified_diff(
+                    golden_contents.splitlines(keepends=True),
+                    generated_contents.splitlines(keepends=True),
+                    fromfile=self.golden_file,
+                    tofile="Generated C++ Header",
+                )
+            ),
+        )
+
+
+if __name__ == "__main__":
+    # This script is not intended to be run directly.
+    # It should be invoked by a test runner.
+    pass
diff --git a/compiler/back_end/cpp/run_one_golden_test.py b/compiler/back_end/cpp/run_one_golden_test.py
new file mode 100644
index 0000000..36f166e
--- /dev/null
+++ b/compiler/back_end/cpp/run_one_golden_test.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python3
+
+# Copyright 2025 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import unittest
+import sys
+import os
+
+sys.path.insert(0, os.path.dirname(__file__))
+
+from one_golden_test import OneGoldenTest
+
+
+def main(argv):
+    if len(argv) < 5:
+        print(
+            f"Usage: {argv[0]} emboss_front_end emboss_compiler emb_file golden_file [include_dir...]"
+        )
+        return 1
+
+    emboss_front_end = argv[1]
+    emboss_compiler = argv[2]
+    emb_file = argv[3]
+    golden_file = argv[4]
+    include_dirs = argv[5:]
+
+    suite = unittest.TestSuite()
+    suite.addTest(
+        OneGoldenTest(
+            emboss_front_end, emboss_compiler, emb_file, golden_file, include_dirs
+        )
+    )
+    runner = unittest.TextTestRunner()
+    result = runner.run(suite)
+    return 0 if result.wasSuccessful() else 1
+
+
+if __name__ == "__main__":
+    sys.exit(main(sys.argv))
diff --git a/compiler/back_end/cpp/testcode/auto_array_size_test.cc b/compiler/back_end/cpp/testcode/auto_array_size_test.cc
index eaae8ec..e3456e2 100644
--- a/compiler/back_end/cpp/testcode/auto_array_size_test.cc
+++ b/compiler/back_end/cpp/testcode/auto_array_size_test.cc
@@ -306,7 +306,7 @@
   auto source = MakeAlignedAutoSizeView<const ::std::uint8_t, 8>(
       kAutoSize, sizeof kAutoSize);
 
-  ::std::array</**/ ::std::uint8_t, sizeof kAutoSize> buf = {0};
+  alignas(8) ::std::array</**/ ::std::uint8_t, sizeof kAutoSize> buf = {0};
   auto dest =
       MakeAlignedAutoSizeView</**/ ::std::uint8_t, 8>(buf.data(), buf.size());
 
diff --git a/compiler/back_end/cpp/testcode/enum_case_test.cc b/compiler/back_end/cpp/testcode/enum_case_test.cc
index 247ad9d..70783c0 100644
--- a/compiler/back_end/cpp/testcode/enum_case_test.cc
+++ b/compiler/back_end/cpp/testcode/enum_case_test.cc
@@ -16,7 +16,11 @@
 // these tests are regarding the name of enum members, it is likely that if this
 // test would fail, it may fail to compile.
 
+#include <cstdint>
+#include <array>
+
 #include "gtest/gtest.h"
+#include "runtime/cpp/emboss_text_util.h"
 #include "testdata/enum_case.emb.h"
 
 namespace emboss {
diff --git a/compiler/back_end/cpp/testcode/importer2_test.cc b/compiler/back_end/cpp/testcode/importer2_test.cc
index 15a24aa..a44b827 100644
--- a/compiler/back_end/cpp/testcode/importer2_test.cc
+++ b/compiler/back_end/cpp/testcode/importer2_test.cc
@@ -14,9 +14,7 @@
 
 // Tests for using types that are imported from imports.
 
-#include <stdint.h>
-
-#include <vector>
+#include <cstdint>
 
 #include "gtest/gtest.h"
 #include "testdata/importer2.emb.h"
diff --git a/compiler/back_end/cpp/testcode/no_enum_traits_test.cc b/compiler/back_end/cpp/testcode/no_enum_traits_test.cc
index 78dbd90..defe7b3 100644
--- a/compiler/back_end/cpp/testcode/no_enum_traits_test.cc
+++ b/compiler/back_end/cpp/testcode/no_enum_traits_test.cc
@@ -18,7 +18,6 @@
 
 #include <vector>
 
-#include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include "testdata/no_enum_traits.emb.h"
 
diff --git a/compiler/front_end/BUILD b/compiler/front_end/BUILD
index fd06d8b..beed67a 100644
--- a/compiler/front_end/BUILD
+++ b/compiler/front_end/BUILD
@@ -73,6 +73,7 @@
         "//compiler/util:ir_data",
         "//compiler/util:name_conversion",
         "//compiler/util:parser_types",
+        "//compiler/util:parser_util",
     ],
 )
 
@@ -436,6 +437,7 @@
         ":module_ir",
         ":tokenizer",
         "//compiler/util:parser_types",
+        "//compiler/util:parser_util",
     ],
 )
 
diff --git a/compiler/front_end/attribute_checker.py b/compiler/front_end/attribute_checker.py
index 9920db4..8da67c1 100644
--- a/compiler/front_end/attribute_checker.py
+++ b/compiler/front_end/attribute_checker.py
@@ -174,7 +174,7 @@
     """Returns size of struct in bits or None, if struct is not fixed size."""
     size = 0
     for field in struct.field:
-        if not field.HasField("location"):
+        if not field.has_field("location"):
             # Virtual fields do not contribute to the physical size of the struct.
             continue
         field_start = ir_util.constant_value(field.location.start)
@@ -421,7 +421,7 @@
     if ir_util.field_is_virtual(field):
         field_expression_type = field.read_transform.type
     else:
-        if not field.type.HasField("atomic_type"):
+        if not field.type.has_field("atomic_type"):
             errors.append(
                 [
                     error.error(
diff --git a/compiler/front_end/attribute_checker_test.py b/compiler/front_end/attribute_checker_test.py
index 4325ca4..fdab7bd 100644
--- a/compiler/front_end/attribute_checker_test.py
+++ b/compiler/front_end/attribute_checker_test.py
@@ -514,12 +514,12 @@
         byte_order_attr = ir_util.get_attribute(
             ir.module[0].type[0].structure.field[0].attribute, _BYTE_ORDER
         )
-        self.assertTrue(byte_order_attr.HasField("string_constant"))
+        self.assertTrue(byte_order_attr.has_field("string_constant"))
         self.assertEqual("BigEndian", byte_order_attr.string_constant.text)
         byte_order_attr = ir_util.get_attribute(
             ir.module[0].type[0].structure.field[1].attribute, _BYTE_ORDER
         )
-        self.assertTrue(byte_order_attr.HasField("string_constant"))
+        self.assertTrue(byte_order_attr.has_field("string_constant"))
         self.assertEqual("LittleEndian", byte_order_attr.string_constant.text)
 
     def test_adds_null_byte_order_attributes(self):
@@ -537,7 +537,7 @@
         byte_order_attr = ir_util.get_attribute(
             structure.field[0].attribute, _BYTE_ORDER
         )
-        self.assertTrue(byte_order_attr.HasField("string_constant"))
+        self.assertTrue(byte_order_attr.has_field("string_constant"))
         self.assertEqual("Null", byte_order_attr.string_constant.text)
         self.assertEqual(
             structure.field[0].source_location, byte_order_attr.source_location
@@ -545,12 +545,12 @@
         byte_order_attr = ir_util.get_attribute(
             structure.field[1].attribute, _BYTE_ORDER
         )
-        self.assertTrue(byte_order_attr.HasField("string_constant"))
+        self.assertTrue(byte_order_attr.has_field("string_constant"))
         self.assertEqual("LittleEndian", byte_order_attr.string_constant.text)
         byte_order_attr = ir_util.get_attribute(
             structure.field[2].attribute, _BYTE_ORDER
         )
-        self.assertTrue(byte_order_attr.HasField("string_constant"))
+        self.assertTrue(byte_order_attr.has_field("string_constant"))
         self.assertEqual("Null", byte_order_attr.string_constant.text)
         self.assertEqual(
             structure.field[2].source_location, byte_order_attr.source_location
@@ -558,7 +558,7 @@
         byte_order_attr = ir_util.get_attribute(
             structure.field[3].attribute, _BYTE_ORDER
         )
-        self.assertTrue(byte_order_attr.HasField("string_constant"))
+        self.assertTrue(byte_order_attr.has_field("string_constant"))
         self.assertEqual("LittleEndian", byte_order_attr.string_constant.text)
 
     def test_disallows_default_byte_order_on_field(self):
@@ -631,7 +631,7 @@
         byte_order_attr = ir_util.get_attribute(
             ir.module[0].type[0].structure.field[0].attribute, _BYTE_ORDER
         )
-        self.assertTrue(byte_order_attr.HasField("string_constant"))
+        self.assertTrue(byte_order_attr.has_field("string_constant"))
         self.assertEqual("BigEndian", byte_order_attr.string_constant.text)
 
     def test_disallows_unknown_byte_order(self):
@@ -926,7 +926,7 @@
         self.assertEqual([], attribute_checker.normalize_and_verify(ir))
         enum = ir.module[0].type[0]
         is_signed_attr = ir_util.get_attribute(enum.attribute, _IS_SIGNED)
-        self.assertTrue(is_signed_attr.expression.HasField("boolean_constant"))
+        self.assertTrue(is_signed_attr.expression.has_field("boolean_constant"))
         self.assertFalse(is_signed_attr.expression.boolean_constant.value)
 
     def test_leaves_is_signed_attribute(self):
@@ -934,7 +934,7 @@
         self.assertEqual([], attribute_checker.normalize_and_verify(ir))
         enum = ir.module[0].type[0]
         is_signed_attr = ir_util.get_attribute(enum.attribute, _IS_SIGNED)
-        self.assertTrue(is_signed_attr.expression.HasField("boolean_constant"))
+        self.assertTrue(is_signed_attr.expression.has_field("boolean_constant"))
         self.assertTrue(is_signed_attr.expression.boolean_constant.value)
 
     def test_adds_true_is_signed_attribute(self):
@@ -942,7 +942,7 @@
         self.assertEqual([], attribute_checker.normalize_and_verify(ir))
         enum = ir.module[0].type[0]
         is_signed_attr = ir_util.get_attribute(enum.attribute, _IS_SIGNED)
-        self.assertTrue(is_signed_attr.expression.HasField("boolean_constant"))
+        self.assertTrue(is_signed_attr.expression.has_field("boolean_constant"))
         self.assertTrue(is_signed_attr.expression.boolean_constant.value)
 
     def test_adds_max_bits_attribute(self):
@@ -950,7 +950,7 @@
         self.assertEqual([], attribute_checker.normalize_and_verify(ir))
         enum = ir.module[0].type[0]
         max_bits_attr = ir_util.get_attribute(enum.attribute, _MAX_BITS)
-        self.assertTrue(max_bits_attr.expression.HasField("constant"))
+        self.assertTrue(max_bits_attr.expression.has_field("constant"))
         self.assertEqual("64", max_bits_attr.expression.constant.value)
 
     def test_leaves_max_bits_attribute(self):
@@ -958,7 +958,7 @@
         self.assertEqual([], attribute_checker.normalize_and_verify(ir))
         enum = ir.module[0].type[0]
         max_bits_attr = ir_util.get_attribute(enum.attribute, _MAX_BITS)
-        self.assertTrue(max_bits_attr.expression.HasField("constant"))
+        self.assertTrue(max_bits_attr.expression.has_field("constant"))
         self.assertEqual("32", max_bits_attr.expression.constant.value)
 
     def test_rejects_too_small_max_bits(self):
diff --git a/compiler/front_end/constraints.py b/compiler/front_end/constraints.py
index 44b884d..ab26a81 100644
--- a/compiler/front_end/constraints.py
+++ b/compiler/front_end/constraints.py
@@ -25,10 +25,10 @@
 
 def _render_type(type_ir, ir):
     """Returns the human-readable notation of the given type."""
-    assert type_ir.HasField(
+    assert type_ir.has_field(
         "atomic_type"
     ), "TODO(bolms): Implement _render_type for array types."
-    if type_ir.HasField("size_in_bits"):
+    if type_ir.has_field("size_in_bits"):
         return _render_atomic_type_name(
             type_ir, ir, suffix=":" + str(ir_util.constant_value(type_ir.size_in_bits))
         )
@@ -37,7 +37,7 @@
 
 
 def _render_atomic_type_name(type_ir, ir, suffix=None):
-    assert type_ir.HasField(
+    assert type_ir.has_field(
         "atomic_type"
     ), "_render_atomic_type_name() requires an atomic type"
     if not suffix:
@@ -78,7 +78,7 @@
 
 def _check_that_array_base_types_are_fixed_size(type_ir, source_file_name, errors, ir):
     """Checks that the sizes of array elements are known at compile time."""
-    if type_ir.base_type.HasField("array_type"):
+    if type_ir.base_type.has_field("array_type"):
         # An array is fixed size if its base_type is fixed size and its array
         # dimension is constant.  This function will be called again on the inner
         # array, and we do not want to cascade errors if the inner array's base_type
@@ -86,8 +86,8 @@
         # _check_that_inner_array_dimensions_are_constant, which will provide an
         # appropriate error message for that case.
         return
-    assert type_ir.base_type.HasField("atomic_type")
-    if type_ir.base_type.HasField("size_in_bits"):
+    assert type_ir.base_type.has_field("atomic_type")
+    if type_ir.base_type.has_field("size_in_bits"):
         # If the base_type has a size_in_bits, then it is fixed size.
         return
     base_type = ir_util.find_object(type_ir.base_type.atomic_type.reference, ir)
@@ -111,11 +111,11 @@
 ):
     # TODO(bolms): Remove this limitation.
     """Checks that the sizes of array elements are multiples of 8 bits."""
-    if type_ir.base_type.HasField("array_type"):
+    if type_ir.base_type.has_field("array_type"):
         # Only check the innermost array for multidimensional arrays.
         return
-    assert type_ir.base_type.HasField("atomic_type")
-    if type_ir.base_type.HasField("size_in_bits"):
+    assert type_ir.base_type.has_field("atomic_type")
+    if type_ir.base_type.has_field("size_in_bits"):
         assert ir_util.is_constant(type_ir.base_type.size_in_bits)
         base_type_size = ir_util.constant_value(type_ir.base_type.size_in_bits)
     else:
@@ -209,10 +209,10 @@
     type_ir, type_definition, field, ir, source_file_name, errors
 ):
     """Checks that the `requires` attribute of each field's type is fulfilled."""
-    if not type_ir.HasField("atomic_type"):
+    if not type_ir.has_field("atomic_type"):
         return
 
-    if field.type.HasField("atomic_type"):
+    if field.type.has_field("atomic_type"):
         field_min_size = (
             int(field.location.size.type.integer.minimum_value)
             * type_definition.addressable_unit
@@ -225,7 +225,7 @@
     else:
         field_is_atomic = False
 
-    if type_ir.HasField("size_in_bits"):
+    if type_ir.has_field("size_in_bits"):
         element_size = ir_util.constant_value(type_ir.size_in_bits)
     else:
         element_size = None
@@ -319,6 +319,49 @@
     )
 
 
+def _check_early_type_requirements_for_parameter_type(
+    runtime_parameter, ir, source_file_name, errors
+):
+    """Checks that the type of a parameter is valid."""
+    physical_type = runtime_parameter.physical_type_alias
+    logical_type = runtime_parameter.type
+    size = ir_util.constant_value(physical_type.size_in_bits)
+    if logical_type.which_type == "integer":
+        # This seems a little weird: for `UInt`, `Int`, etc., the explicit size
+        # is required, but for enums it is banned.  This is because enums have
+        # a "natural" size (the size specified in the `enum` definition, or 64
+        # bits by default) in expressions, so the physical size would just be
+        # ignored.  Integer types do not have "natural" sizes, so the width is
+        # required.
+        if not physical_type.has_field("size_in_bits"):
+            errors.extend(
+                [
+                    [
+                        error.error(
+                            source_file_name,
+                            physical_type.source_location,
+                            f"Parameters with integer type must have explicit size (e.g., `{physical_type.atomic_type.reference.source_name[-1].text}:32`).",
+                        )
+                    ]
+                ]
+            )
+    elif logical_type.which_type == "enumeration":
+        if physical_type.has_field("size_in_bits"):
+            errors.extend(
+                [
+                    [
+                        error.error(
+                            source_file_name,
+                            physical_type.size_in_bits.source_location,
+                            "Parameters with enum type may not have explicit size.",
+                        )
+                    ]
+                ]
+            )
+    else:
+        assert False, "Non-integer/enum parameters should have been caught earlier."
+
+
 def _check_type_requirements_for_parameter_type(
     runtime_parameter, ir, source_file_name, errors
 ):
@@ -346,22 +389,7 @@
             )
         )
     elif logical_type.which_type == "enumeration":
-        if physical_type.HasField("size_in_bits"):
-            # This seems a little weird: for `UInt`, `Int`, etc., the explicit size is
-            # required, but for enums it is banned.  This is because enums have a
-            # "native" 64-bit size in expressions, so the physical size is just
-            # ignored.
-            errors.extend(
-                [
-                    [
-                        error.error(
-                            source_file_name,
-                            physical_type.size_in_bits.source_location,
-                            "Parameters with enum type may not have explicit size.",
-                        )
-                    ]
-                ]
-            )
+        pass
     else:
         assert False, "Non-integer/enum parameters should have been caught earlier."
 
@@ -371,7 +399,7 @@
 ):
     """Checks that the given atomic `type_ir` is allowed to be `size` bits."""
     referenced_type_definition = ir_util.find_object(type_ir.atomic_type.reference, ir)
-    if referenced_type_definition.HasField("enumeration"):
+    if referenced_type_definition.has_field("enumeration"):
         if size is None:
             return [
                 [
@@ -437,7 +465,7 @@
 
 def _check_allowed_in_bits(type_ir, type_definition, source_file_name, ir, errors):
     """Verifies that atomic fields have types that are allowed in `bits`."""
-    if not type_ir.HasField("atomic_type"):
+    if not type_ir.has_field("atomic_type"):
         return
     referenced_type_definition = ir_util.find_object(type_ir.atomic_type.reference, ir)
     if (
@@ -686,6 +714,17 @@
     return {"in_attribute": a}
 
 
+def check_early_constraints(ir):
+    errors = []
+    traverse_ir.fast_traverse_ir_top_down(
+        ir,
+        [ir_data.RuntimeParameter],
+        _check_early_type_requirements_for_parameter_type,
+        parameters={"errors": errors},
+    )
+    return errors
+
+
 def check_constraints(ir):
     """Checks miscellaneous validity constraints in ir.
 
diff --git a/compiler/front_end/constraints_test.py b/compiler/front_end/constraints_test.py
index 4f4df7e..fb790a9 100644
--- a/compiler/front_end/constraints_test.py
+++ b/compiler/front_end/constraints_test.py
@@ -24,11 +24,11 @@
 from compiler.util import test_util
 
 
-def _make_ir_from_emb(emb_text, name="m.emb"):
+def _make_ir_from_emb(emb_text, name="m.emb", stop_before_step="check_constraints"):
     ir, unused_debug_info, errors = glue.parse_emboss_file(
         name,
         test_util.dict_file_reader({name: emb_text}),
-        stop_before_step="check_constraints",
+        stop_before_step=stop_before_step,
     )
     assert not errors, repr(errors)
     return ir
@@ -1252,8 +1252,12 @@
             error.filter_errors(constraints.check_constraints(ir)),
         )
 
-    def test_checks_for_explicit_size_on_parameters(self):
-        ir = _make_ir_from_emb("struct Foo(y: UInt):\n" "  0 [+1]  UInt  x\n")
+    def test_checks_for_explicit_integer_size_on_parameters(self):
+        ir = _make_ir_from_emb(
+            "struct Foo(y: UInt):\n"  #
+            "  0 [+1]  UInt  x\n",
+            stop_before_step="check_early_constraints",
+        )
         error_parameter = ir.module[0].type[0].runtime_parameter[0]
         error_location = error_parameter.physical_type_alias.source_location
         self.assertEqual(
@@ -1262,12 +1266,34 @@
                     error.error(
                         "m.emb",
                         error_location,
-                        "Integer range of parameter must not be unbounded; it "
-                        "must fit in a 64-bit signed or unsigned integer.",
+                        "Parameters with integer type must have explicit size (e.g., `UInt:32`).",
                     )
                 ]
             ],
-            error.filter_errors(constraints.check_constraints(ir)),
+            error.filter_errors(constraints.check_early_constraints(ir)),
+        )
+
+    def test_checks_for_explicit_integer_size_on_parameters_and_uses_type_in_error(
+        self,
+    ):
+        ir = _make_ir_from_emb(
+            "struct Foo(y: Int):\n"  #
+            "  0 [+1]  UInt  x\n",
+            stop_before_step="check_early_constraints",
+        )
+        error_parameter = ir.module[0].type[0].runtime_parameter[0]
+        error_location = error_parameter.physical_type_alias.source_location
+        self.assertEqual(
+            [
+                [
+                    error.error(
+                        "m.emb",
+                        error_location,
+                        "Parameters with integer type must have explicit size (e.g., `Int:32`).",
+                    )
+                ]
+            ],
+            error.filter_errors(constraints.check_early_constraints(ir)),
         )
 
     def test_checks_for_correct_explicit_size_on_parameters(self):
@@ -1292,7 +1318,11 @@
 
     def test_checks_for_explicit_enum_size_on_parameters(self):
         ir = _make_ir_from_emb(
-            "struct Foo(y: Bar:8):\n" "  0 [+1]  UInt  x\n" "enum Bar:\n" "  QUX = 1\n"
+            "struct Foo(y: Bar:8):\n"  #
+            "  0 [+1]  UInt  x\n"
+            "enum Bar:\n"
+            "  QUX = 1\n",
+            stop_before_step="check_early_constraints",
         )
         error_parameter = ir.module[0].type[0].runtime_parameter[0]
         error_size = error_parameter.physical_type_alias.size_in_bits
@@ -1307,7 +1337,7 @@
                     )
                 ]
             ],
-            error.filter_errors(constraints.check_constraints(ir)),
+            error.filter_errors(constraints.check_early_constraints(ir)),
         )
 
 
diff --git a/compiler/front_end/expression_bounds.py b/compiler/front_end/expression_bounds.py
index 51efca5..64e93fa 100644
--- a/compiler/front_end/expression_bounds.py
+++ b/compiler/front_end/expression_bounds.py
@@ -144,19 +144,22 @@
         expression.type.integer.modulus = "1"
         expression.type.integer.modular_value = "0"
         type_definition = ir_util.find_parent_object(field_path, ir)
+        type_size = None
         if isinstance(field, ir_data.Field):
             referrent_type = field.type
         else:
             referrent_type = field.physical_type_alias
-        if referrent_type.HasField("size_in_bits"):
+        if referrent_type.has_field("size_in_bits"):
             type_size = ir_util.constant_value(referrent_type.size_in_bits)
-        else:
+        elif isinstance(field, ir_data.Field):
             field_size = ir_util.constant_value(field.location.size)
             if field_size is None:
                 type_size = None
             else:
                 type_size = field_size * type_definition.addressable_unit
-        assert referrent_type.HasField("atomic_type"), field
+        else:
+            type_size = None
+        assert referrent_type.has_field("atomic_type"), field
         assert not referrent_type.atomic_type.reference.canonical_name.module_file
         _set_integer_constraints_from_physical_type(
             expression, referrent_type, type_size
@@ -665,7 +668,7 @@
     """Computes the constraints of a choice operation '?:'."""
     condition, if_true, if_false = ir_data_utils.reader(expression).function.args
     expression = ir_data_utils.builder(expression)
-    if condition.type.boolean.HasField("value"):
+    if condition.type.boolean.has_field("value"):
         # The generated expressions for $size_in_bits and $size_in_bytes look like
         #
         #     $max((field1_existence_condition ? field1_start + field1_size : 0),
diff --git a/compiler/front_end/expression_bounds_test.py b/compiler/front_end/expression_bounds_test.py
index e5bc25d..d6428b7 100644
--- a/compiler/front_end/expression_bounds_test.py
+++ b/compiler/front_end/expression_bounds_test.py
@@ -44,7 +44,7 @@
         ir = self._make_ir("struct Foo:\n" "  if true:\n" "    0 [+1]  UInt  x\n")
         self.assertEqual([], expression_bounds.compute_constants(ir))
         expression = ir.module[0].type[0].structure.field[0].existence_condition
-        self.assertTrue(expression.type.boolean.HasField("value"))
+        self.assertTrue(expression.type.boolean.has_field("value"))
         self.assertTrue(expression.type.boolean.value)
 
     def test_constant_equality(self):
@@ -59,9 +59,9 @@
         structure = ir.module[0].type[0].structure
         true_condition = structure.field[0].existence_condition
         false_condition = structure.field[1].existence_condition
-        self.assertTrue(true_condition.type.boolean.HasField("value"))
+        self.assertTrue(true_condition.type.boolean.has_field("value"))
         self.assertTrue(true_condition.type.boolean.value)
-        self.assertTrue(false_condition.type.boolean.HasField("value"))
+        self.assertTrue(false_condition.type.boolean.has_field("value"))
         self.assertFalse(false_condition.type.boolean.value)
 
     def test_constant_inequality(self):
@@ -76,9 +76,9 @@
         structure = ir.module[0].type[0].structure
         false_condition = structure.field[0].existence_condition
         true_condition = structure.field[1].existence_condition
-        self.assertTrue(false_condition.type.boolean.HasField("value"))
+        self.assertTrue(false_condition.type.boolean.has_field("value"))
         self.assertFalse(false_condition.type.boolean.value)
-        self.assertTrue(true_condition.type.boolean.HasField("value"))
+        self.assertTrue(true_condition.type.boolean.has_field("value"))
         self.assertTrue(true_condition.type.boolean.value)
 
     def test_constant_less_than(self):
@@ -96,11 +96,11 @@
         greater_than_condition = structure.field[0].existence_condition
         equal_condition = structure.field[1].existence_condition
         less_than_condition = structure.field[2].existence_condition
-        self.assertTrue(greater_than_condition.type.boolean.HasField("value"))
+        self.assertTrue(greater_than_condition.type.boolean.has_field("value"))
         self.assertFalse(greater_than_condition.type.boolean.value)
-        self.assertTrue(equal_condition.type.boolean.HasField("value"))
+        self.assertTrue(equal_condition.type.boolean.has_field("value"))
         self.assertFalse(equal_condition.type.boolean.value)
-        self.assertTrue(less_than_condition.type.boolean.HasField("value"))
+        self.assertTrue(less_than_condition.type.boolean.has_field("value"))
         self.assertTrue(less_than_condition.type.boolean.value)
 
     def test_constant_less_than_or_equal(self):
@@ -118,11 +118,11 @@
         greater_than_condition = structure.field[0].existence_condition
         equal_condition = structure.field[1].existence_condition
         less_than_condition = structure.field[2].existence_condition
-        self.assertTrue(greater_than_condition.type.boolean.HasField("value"))
+        self.assertTrue(greater_than_condition.type.boolean.has_field("value"))
         self.assertFalse(greater_than_condition.type.boolean.value)
-        self.assertTrue(equal_condition.type.boolean.HasField("value"))
+        self.assertTrue(equal_condition.type.boolean.has_field("value"))
         self.assertTrue(equal_condition.type.boolean.value)
-        self.assertTrue(less_than_condition.type.boolean.HasField("value"))
+        self.assertTrue(less_than_condition.type.boolean.has_field("value"))
         self.assertTrue(less_than_condition.type.boolean.value)
 
     def test_constant_greater_than(self):
@@ -140,11 +140,11 @@
         greater_than_condition = structure.field[0].existence_condition
         equal_condition = structure.field[1].existence_condition
         less_than_condition = structure.field[2].existence_condition
-        self.assertTrue(greater_than_condition.type.boolean.HasField("value"))
+        self.assertTrue(greater_than_condition.type.boolean.has_field("value"))
         self.assertTrue(greater_than_condition.type.boolean.value)
-        self.assertTrue(equal_condition.type.boolean.HasField("value"))
+        self.assertTrue(equal_condition.type.boolean.has_field("value"))
         self.assertFalse(equal_condition.type.boolean.value)
-        self.assertTrue(less_than_condition.type.boolean.HasField("value"))
+        self.assertTrue(less_than_condition.type.boolean.has_field("value"))
         self.assertFalse(less_than_condition.type.boolean.value)
 
     def test_constant_greater_than_or_equal(self):
@@ -162,11 +162,11 @@
         greater_than_condition = structure.field[0].existence_condition
         equal_condition = structure.field[1].existence_condition
         less_than_condition = structure.field[2].existence_condition
-        self.assertTrue(greater_than_condition.type.boolean.HasField("value"))
+        self.assertTrue(greater_than_condition.type.boolean.has_field("value"))
         self.assertTrue(greater_than_condition.type.boolean.value)
-        self.assertTrue(equal_condition.type.boolean.HasField("value"))
+        self.assertTrue(equal_condition.type.boolean.has_field("value"))
         self.assertTrue(equal_condition.type.boolean.value)
-        self.assertTrue(less_than_condition.type.boolean.HasField("value"))
+        self.assertTrue(less_than_condition.type.boolean.has_field("value"))
         self.assertFalse(less_than_condition.type.boolean.value)
 
     def test_constant_and(self):
@@ -187,13 +187,13 @@
         true_false_condition = structure.field[1].existence_condition
         false_true_condition = structure.field[2].existence_condition
         true_true_condition = structure.field[3].existence_condition
-        self.assertTrue(false_false_condition.type.boolean.HasField("value"))
+        self.assertTrue(false_false_condition.type.boolean.has_field("value"))
         self.assertFalse(false_false_condition.type.boolean.value)
-        self.assertTrue(true_false_condition.type.boolean.HasField("value"))
+        self.assertTrue(true_false_condition.type.boolean.has_field("value"))
         self.assertFalse(true_false_condition.type.boolean.value)
-        self.assertTrue(false_true_condition.type.boolean.HasField("value"))
+        self.assertTrue(false_true_condition.type.boolean.has_field("value"))
         self.assertFalse(false_true_condition.type.boolean.value)
-        self.assertTrue(true_true_condition.type.boolean.HasField("value"))
+        self.assertTrue(true_true_condition.type.boolean.has_field("value"))
         self.assertTrue(true_true_condition.type.boolean.value)
 
     def test_constant_or(self):
@@ -214,13 +214,13 @@
         true_false_condition = structure.field[1].existence_condition
         false_true_condition = structure.field[2].existence_condition
         true_true_condition = structure.field[3].existence_condition
-        self.assertTrue(false_false_condition.type.boolean.HasField("value"))
+        self.assertTrue(false_false_condition.type.boolean.has_field("value"))
         self.assertFalse(false_false_condition.type.boolean.value)
-        self.assertTrue(true_false_condition.type.boolean.HasField("value"))
+        self.assertTrue(true_false_condition.type.boolean.has_field("value"))
         self.assertTrue(true_false_condition.type.boolean.value)
-        self.assertTrue(false_true_condition.type.boolean.HasField("value"))
+        self.assertTrue(false_true_condition.type.boolean.has_field("value"))
         self.assertTrue(false_true_condition.type.boolean.value)
-        self.assertTrue(true_true_condition.type.boolean.HasField("value"))
+        self.assertTrue(true_true_condition.type.boolean.has_field("value"))
         self.assertTrue(true_true_condition.type.boolean.value)
 
     def test_enum_constant(self):
@@ -276,7 +276,7 @@
         self.assertEqual([], expression_bounds.compute_constants(ir))
         structure = ir.module[0].type[0].structure
         condition = structure.field[0].existence_condition
-        self.assertFalse(condition.type.boolean.HasField("value"))
+        self.assertFalse(condition.type.boolean.has_field("value"))
 
     def test_constant_addition(self):
         ir = self._make_ir("struct Foo:\n" "  7+5 [+1]  UInt  x\n")
@@ -864,7 +864,7 @@
         self.assertEqual([], expression_bounds.compute_constants(ir))
         field = ir.module[0].type[0].structure.field[0]
         has_func = field.existence_condition
-        self.assertTrue(has_func.type.boolean.HasField("value"))
+        self.assertTrue(has_func.type.boolean.has_field("value"))
         self.assertFalse(has_func.type.boolean.value)
 
     def test_variable_has(self):
@@ -881,7 +881,7 @@
         self.assertEqual([], expression_bounds.compute_constants(ir))
         field = ir.module[0].type[0].structure.field[0]
         has_func = field.existence_condition
-        self.assertFalse(has_func.type.boolean.HasField("value"))
+        self.assertFalse(has_func.type.boolean.has_field("value"))
 
     def test_max_of_constants(self):
         ir = self._make_ir(
@@ -1008,7 +1008,7 @@
         self.assertEqual([], expression_bounds.compute_constants(ir))
         expr = ir.module[0].type[0].structure.field[1].existence_condition
         self.assertEqual("boolean", expr.type.which_type)
-        self.assertFalse(expr.type.boolean.HasField("value"))
+        self.assertFalse(expr.type.boolean.has_field("value"))
 
     def test_uint_value_range_for_explicit_size(self):
         ir = self._make_ir(
diff --git a/compiler/front_end/format_emb.py b/compiler/front_end/format_emb.py
index fc7bf94..f0b0137 100644
--- a/compiler/front_end/format_emb.py
+++ b/compiler/front_end/format_emb.py
@@ -26,6 +26,7 @@
 from compiler.front_end import module_ir
 from compiler.front_end import tokenizer
 from compiler.util import parser_types
+from compiler.util import parser_util
 
 
 class Config(collections.namedtuple("Config", ["indent_width", "show_line_types"])):
@@ -67,18 +68,17 @@
     Returns:
         A string of the reformatted source text.
     """
-    if hasattr(parse_tree, "children"):
-        parsed_children = [
-            format_emboss_parse_tree(child, config, used_productions)
-            for child in parse_tree.children
-        ]
-        args = parsed_children + [config]
-        if used_productions is not None:
-            used_productions.add(parse_tree.production)
-        return _formatters[parse_tree.production](*args)
-    else:
-        assert isinstance(parse_tree, parser_types.Token), str(parse_tree)
-        return parse_tree.text
+    formatters = {}
+    for production, handler in _formatters.items():
+        # An extra layer of indirection is required here so that the resulting
+        # lambda does not capture the local variable `handler`.
+        def wrapped_handler(handler):
+            return lambda _, *args: handler(*(args + (config,)))
+
+        formatters[production] = wrapped_handler(handler)
+    return parser_util.transform_parse_tree(
+        parse_tree, lambda n: n.text, formatters, used_productions
+    )
 
 
 def sanity_check_format_result(formatted_text, original_text):
diff --git a/compiler/front_end/format_emb_test.py b/compiler/front_end/format_emb_test.py
index 3d5331e..42d8a26 100644
--- a/compiler/front_end/format_emb_test.py
+++ b/compiler/front_end/format_emb_test.py
@@ -92,7 +92,21 @@
 
 
 class FormatEmbTest(unittest.TestCase):
-    pass
+
+    def test_very_long_emb(self):
+        """Checks that very long inputs do not hit the Python recursion limit."""
+        emb = ["enum Test:\n"]
+        # Enough entities to blow through the default recursion limit and the
+        # bumped limit that was previously in place.
+        for i in range(max(sys.getrecursionlimit(), 16 * 1024) * 2):
+            emb.append(f"  VALUE_{i} = {i}\n")
+        parsed_unformatted = parser.parse_module(
+            tokenizer.tokenize("".join(emb), "long.emb")[0]
+        )
+        formatted_text = format_emb.format_emboss_parse_tree(
+            parsed_unformatted.parse_tree,
+            format_emb.Config(indent_width=2),
+        )
 
 
 def _make_golden_file_tests():
diff --git a/compiler/front_end/glue.py b/compiler/front_end/glue.py
index f12f27e..b6d1534 100644
--- a/compiler/front_end/glue.py
+++ b/compiler/front_end/glue.py
@@ -203,7 +203,7 @@
     """
     source_code, errors = file_reader(file_name)
     if errors:
-        location = parser_types.make_location((1, 1), (1, 1))
+        location = parser_types.SourceLocation((1, 1), (1, 1))
         return (
             None,
             None,
@@ -319,6 +319,7 @@
         symbol_resolver.resolve_field_references,
         type_check.annotate_types,
         type_check.check_types,
+        constraints.check_early_constraints,
         expression_bounds.compute_constants,
         attribute_checker.normalize_and_verify,
         constraints.check_constraints,
diff --git a/compiler/front_end/glue_test.py b/compiler/front_end/glue_test.py
index 1decae3..fface8a 100644
--- a/compiler/front_end/glue_test.py
+++ b/compiler/front_end/glue_test.py
@@ -24,7 +24,7 @@
 from compiler.util import parser_types
 from compiler.util import test_util
 
-_location = parser_types.make_location
+_location = parser_types.SourceLocation
 
 _ROOT_PACKAGE = "testdata.golden"
 _GOLDEN_PATH = ""
@@ -232,7 +232,9 @@
         self.assertFalse(errors)
         # Artificially mark the first field as is_synthetic.
         first_field = ir.module[0].type[0].structure.field[0]
-        first_field.source_location.is_synthetic = True
+        first_field.source_location = first_field.source_location._replace(
+            is_synthetic=True
+        )
         ir, errors = glue.process_ir(ir, None)
         self.assertTrue(errors)
         self.assertEqual(
@@ -259,8 +261,12 @@
         self.assertFalse(errors)
         # Artificially mark the name of the second field as is_synthetic.
         second_field = ir.module[0].type[0].structure.field[1]
-        second_field.name.source_location.is_synthetic = True
-        second_field.name.name.source_location.is_synthetic = True
+        second_field.name.source_location = second_field.name.source_location._replace(
+            is_synthetic=True
+        )
+        second_field.name.name.source_location = (
+            second_field.name.name.source_location._replace(is_synthetic=True)
+        )
         ir, errors = glue.process_ir(ir, None)
         self.assertEqual(1, len(errors))
         self.assertEqual("Duplicate name 'field'", errors[0][0].message)
diff --git a/compiler/front_end/lr1.py b/compiler/front_end/lr1.py
index 58d5076..42c648b 100644
--- a/compiler/front_end/lr1.py
+++ b/compiler/front_end/lr1.py
@@ -140,7 +140,9 @@
 
 # ANY_TOKEN is used by mark_error as a "wildcard" token that should be replaced
 # by every other token.
-ANY_TOKEN = parser_types.Token(object(), "*", parser_types.parse_location("0:0-0:0"))
+ANY_TOKEN = parser_types.Token(
+    object(), "*", parser_types.SourceLocation.from_str("0:0-0:0")
+)
 
 
 class Reduction(
@@ -690,26 +692,7 @@
                 # children, setting the source_location to None in that case.
                 start_position = None
                 end_position = None
-                for child in children:
-                    if (
-                        hasattr(child, "source_location")
-                        and child.source_location is not None
-                    ):
-                        start_position = child.source_location.start
-                        break
-                for child in reversed(children):
-                    if (
-                        hasattr(child, "source_location")
-                        and child.source_location is not None
-                    ):
-                        end_position = child.source_location.end
-                        break
-                if start_position is None:
-                    source_location = None
-                else:
-                    source_location = parser_types.make_location(
-                        start_position, end_position
-                    )
+                source_location = parser_types.merge_source_locations(*children)
                 reduction = Reduction(
                     next_action.rule.lhs, children, next_action.rule, source_location
                 )
diff --git a/compiler/front_end/lr1_test.py b/compiler/front_end/lr1_test.py
index 6ca6e67..0415102 100644
--- a/compiler/front_end/lr1_test.py
+++ b/compiler/front_end/lr1_test.py
@@ -34,7 +34,7 @@
     result = []
     for i in range(len(text)):
         result.append(
-            Token(text[i], parser_types.make_location((1, i + 1), (1, i + 2)))
+            Token(text[i], parser_types.SourceLocation((1, i + 1), (1, i + 2)))
         )
     return result
 
@@ -209,7 +209,7 @@
 
     def test_successful_parse(self):
         parser = _alsu_grammar.parser()
-        loc = parser_types.parse_location
+        loc = parser_types.SourceLocation.from_str
         s_to_c_c = parser_types.Production.parse("S -> C C")
         c_to_c_c = parser_types.Production.parse("C -> c C")
         c_to_d = parser_types.Production.parse("C -> d")
@@ -340,7 +340,7 @@
             parser.mark_error([lr1.ANY_TOKEN], lr1.ANY_TOKEN, "default error")
         )
         # Marking an already-marked error with a different error code should fail.
-        self.assertRegexpMatches(
+        self.assertRegex(
             parser.mark_error([lr1.ANY_TOKEN], lr1.ANY_TOKEN, "default error 2"),
             r"^Attempted to overwrite existing default error code 'default error' "
             r"with new error code 'default error 2' for state \d+$",
diff --git a/compiler/front_end/module_ir.py b/compiler/front_end/module_ir.py
index 4a459c2..2871797 100644
--- a/compiler/front_end/module_ir.py
+++ b/compiler/front_end/module_ir.py
@@ -29,6 +29,7 @@
 from compiler.util import ir_data_utils
 from compiler.util import name_conversion
 from compiler.util import parser_types
+from compiler.util import parser_util
 
 
 # Intermediate types; should not be found in the final IR.
@@ -40,7 +41,7 @@
     def __init__(self, l):
         assert isinstance(l, list), "_List object must wrap list, not '%r'" % l
         self.list = l
-        self.source_location = ir_data.Location()
+        self.source_location = parser_types.SourceLocation()
 
 
 class _ExpressionTail(object):
@@ -65,7 +66,7 @@
     def __init__(self, operator, expression):
         self.operator = operator
         self.expression = expression
-        self.source_location = ir_data.Location()
+        self.source_location = parser_types.SourceLocation()
 
 
 class _FieldWithType(object):
@@ -76,94 +77,84 @@
     def __init__(self, field, subtypes=None):
         self.field = field
         self.subtypes = subtypes or []
-        self.source_location = ir_data.Location()
+        self.source_location = parser_types.SourceLocation()
 
 
 def build_ir(parse_tree, used_productions=None):
     r"""Builds a module-level intermediate representation from a valid parse tree.
 
-  The parse tree is precisely dictated by the exact productions in the grammar
-  used by the parser, with no semantic information.  _really_build_ir transforms
-  this "raw" form into a stable, cooked representation, thereby isolating
-  subsequent steps from the exact details of the grammar.
-
-  (Probably incomplete) list of transformations:
-
-  *   ParseResult and Token nodes are replaced with Module, Attribute, Struct,
-      Type, etc. objects.
-
-  *   Purely syntactic tokens ('"["', '"struct"', etc.) are discarded.
-
-  *   Repeated elements are transformed from tree form to list form:
-
-          a*
-         / \
-        b   a*
+    The parse tree is precisely dictated by the exact productions in the grammar
+    used by the parser, with no semantic information.  _really_build_ir
+    transforms this "raw" form into a stable, cooked representation, thereby
+    isolating subsequent steps from the exact details of the grammar.
+    
+    (Probably incomplete) list of transformations:
+    
+    *   ParseResult and Token nodes are replaced with Module, Attribute, Struct,
+        Type, etc. objects.
+    
+    *   Purely syntactic tokens ('"["', '"struct"', etc.) are discarded.
+    
+    *   Repeated elements are transformed from tree form to list form:
+    
+            a*
            / \
-          c   a*
+          b   a*
              / \
-            d   a*
+            c   a*
+               / \
+              d   a*
+    
+        (where b, c, and d are nodes of type "a") becomes [b, c, d].
+    
+    *   The values of numeric constants (Number, etc. tokens) are parsed.
+    
+    *   Different classes of names (snake_names, CamelNames, ShoutyNames) are
+        folded into a single "Name" type, since they are guaranteed to appear in
+        the correct places in the parse tree.
+    
+    
+    Arguments:
+        parse_tree: A parse tree.  Each leaf node should be a parser_types.Token
+            object, and each non-leaf node should have a 'symbol' attribute
+            specifying which grammar symbol it represents, and a 'children'
+            attribute containing a list of child nodes.  This is the format
+            returned by the parsers produced by the lr1 module, when run
+            against tokens from the tokenizer module.
+        used_productions: If specified, used_productions.add() will be called
+            with each production actually used in parsing.  This can be useful
+            when developing the grammar and writing tests; in particular, it
+            can be used to figure out which productions are *not* used when
+            parsing a particular file.
+    
+    Returns:
+        A module-level intermediate representation (module IR) for an Emboss
+        module (source file).  This IR will not have symbols resolved,
+        constraints checked, fields synthesized, etc.; it will only be a
+        representation of the syntactic elements of the source.
+    """
+    handlers = {}
+    for production, handler in _handlers.items():
+        # An extra layer of indirection is required here so that the resulting
+        # lambda does not capture the local variable `handler`.
+        def wrapped_handler(handler):
+            def wrapped_handler(node, *args):
+                module_node = handler(*args)
+                if node.source_location:
+                    if isinstance(module_node, tuple):
+                        module_node = module_node._replace(
+                            source_location=node.source_location
+                        )
+                    else:
+                        module_node.source_location = node.source_location
+                return module_node
 
-      (where b, c, and d are nodes of type "a") becomes [b, c, d].
+            return wrapped_handler
 
-  *   The values of numeric constants (Number, etc. tokens) are parsed.
-
-  *   Different classes of names (snake_names, CamelNames, ShoutyNames) are
-      folded into a single "Name" type, since they are guaranteed to appear in
-      the correct places in the parse tree.
-
-
-  Arguments:
-    parse_tree: A parse tree.  Each leaf node should be a parser_types.Token
-      object, and each non-leaf node should have a 'symbol' attribute specifying
-      which grammar symbol it represents, and a 'children' attribute containing
-      a list of child nodes.  This is the format returned by the parsers
-      produced by the lr1 module, when run against tokens from the tokenizer
-      module.
-    used_productions: If specified, used_productions.add() will be called with
-      each production actually used in parsing.  This can be useful when
-      developing the grammar and writing tests; in particular, it can be used to
-      figure out which productions are *not* used when parsing a particular
-      file.
-
-  Returns:
-    A module-level intermediate representation (module IR) for an Emboss module
-    (source file).  This IR will not have symbols resolved; that must be done on
-    a forest of module IRs so that names from other modules can be resolved.
-  """
-
-    # TODO(b/140259131): Refactor _really_build_ir to be less recursive/use an
-    # explicit stack.
-    old_recursion_limit = sys.getrecursionlimit()
-    sys.setrecursionlimit(16 * 1024)  # ~8000 top-level entities in one module.
-    try:
-        result = _really_build_ir(parse_tree, used_productions)
-    finally:
-        sys.setrecursionlimit(old_recursion_limit)
-    return result
-
-
-def _really_build_ir(parse_tree, used_productions):
-    """Real implementation of build_ir()."""
-    if used_productions is None:
-        used_productions = set()
-    if hasattr(parse_tree, "children"):
-        parsed_children = [
-            _really_build_ir(child, used_productions) for child in parse_tree.children
-        ]
-        used_productions.add(parse_tree.production)
-        result = _handlers[parse_tree.production](*parsed_children)
-        if parse_tree.source_location is not None:
-            if result.source_location:
-                ir_data_utils.update(result.source_location, parse_tree.source_location)
-            else:
-                result.source_location = ir_data_utils.copy(parse_tree.source_location)
-        return result
-    else:
-        # For leaf nodes, the temporary "IR" is just the token.  Higher-level rules
-        # will translate it to a real IR.
-        assert isinstance(parse_tree, parser_types.Token), str(parse_tree)
-        return parse_tree
+        handlers[production] = wrapped_handler(handler)
+    return parser_util.transform_parse_tree(
+        parse_tree, lambda n: n, handlers, used_productions
+    )
 
 
 # Map of productions to their handlers.
@@ -191,7 +182,7 @@
 
 def _make_prelude_import(position):
     """Helper function to construct a synthetic ir_data.Import for the prelude."""
-    location = parser_types.make_location(position, position)
+    location = parser_types.SourceLocation(position, position)
     return ir_data.Import(
         file_name=ir_data.String(text="", source_location=location),
         local_name=ir_data.Word(text="", source_location=location),
@@ -279,7 +270,7 @@
         and not attributes.list
         and not type_definitions.list
     ):
-        module_source_location = parser_types.make_location((1, 1), (1, 1))
+        module_source_location = parser_types.SourceLocation((1, 1), (1, 1))
     else:
         module_source_location = None
 
@@ -462,10 +453,10 @@
 )
 def _choice_expression(condition, question, if_true, colon, if_false):
     """Constructs an IR node for a choice operator (`?:`) expression."""
-    location = parser_types.make_location(
+    location = parser_types.SourceLocation(
         condition.source_location.start, if_false.source_location.end
     )
-    operator_location = parser_types.make_location(
+    operator_location = parser_types.SourceLocation(
         question.source_location.start, colon.source_location.end
     )
     # The function_name is a bit weird, but should suffice for any error
@@ -490,7 +481,7 @@
     "    additive-expression inequality-operator additive-expression"
 )
 def _comparative_expression(left, operator, right):
-    location = parser_types.make_location(
+    location = parser_types.SourceLocation(
         left.source_location.start, right.source_location.end
     )
     return ir_data.Expression(
@@ -538,7 +529,7 @@
     """
     e = expression
     for right in expression_right.list:
-        location = parser_types.make_location(
+        location = parser_types.SourceLocation(
             e.source_location.start, right.source_location.end
         )
         e = ir_data.Expression(
@@ -611,7 +602,7 @@
     comparisons = []
     for i in range(0, len(sequence) - 1, 2):
         left, operator, right = sequence[i : i + 3]
-        location = parser_types.make_location(
+        location = parser_types.SourceLocation(
             left.source_location.start, right.source_location.end
         )
         comparisons.append(
@@ -627,7 +618,7 @@
         )
     e = comparisons[0]
     for comparison in comparisons[1:]:
-        location = parser_types.make_location(
+        location = parser_types.SourceLocation(
             e.source_location.start, comparison.source_location.end
         )
         e = ir_data.Expression(
@@ -717,7 +708,7 @@
 # allowed, but "+-5" or "-+-something" are not.
 @_handles("negation-expression -> additive-operator bottom-expression")
 def _negation_expression_with_operator(operator, expression):
-    phantom_zero_location = ir_data.Location(
+    phantom_zero_location = parser_types.SourceLocation(
         start=operator.source_location.start, end=operator.source_location.start
     )
     return ir_data.Expression(
@@ -733,7 +724,7 @@
                 expression,
             ],
             function_name=operator,
-            source_location=ir_data.Location(
+            source_location=parser_types.SourceLocation(
                 start=operator.source_location.start, end=expression.source_location.end
             ),
         )
@@ -759,7 +750,7 @@
             function=_text_to_function(function.text),
             args=arguments.list,
             function_name=function,
-            source_location=ir_data.Location(
+            source_location=parser_types.SourceLocation(
                 start=function.source_location.start,
                 end=close_paren.source_location.end,
             ),
@@ -811,15 +802,11 @@
 
 @_handles("field-reference -> snake-reference field-reference-tail*")
 def _indirect_field_reference(field_reference, field_references):
-    if field_references.source_location.HasField("end"):
-        end_location = field_references.source_location.end
-    else:
-        end_location = field_reference.source_location.end
     return ir_data.Expression(
         field_reference=ir_data.FieldReference(
             path=[field_reference] + field_references.list,
-            source_location=parser_types.make_location(
-                field_reference.source_location.start, end_location
+            source_location=parser_types.merge_source_locations(
+                field_reference, field_references
             ),
         )
     )
@@ -869,11 +856,8 @@
 def _structure(struct, name, parameters, colon, comment, newline, struct_body):
     """Composes the top-level IR for an Emboss structure."""
     del colon, comment, newline  # Unused.
-    ir_data_utils.builder(struct_body.structure).source_location.start.CopyFrom(
-        struct.source_location.start
-    )
-    ir_data_utils.builder(struct_body.structure).source_location.end.CopyFrom(
-        struct_body.source_location.end
+    ir_data_utils.builder(struct_body.structure).source_location = (
+        parser_types.merge_source_locations(struct, struct_body)
     )
     if struct_body.name:
         ir_data_utils.update(struct_body.name, name)
@@ -969,14 +953,12 @@
 )
 def _unconditional_block_plus_field_block(field, block):
     """Prepends an unconditional field to block."""
-    ir_data_utils.builder(field.field).existence_condition.source_location.CopyFrom(
+    ir_data_utils.builder(field.field).existence_condition.source_location = (
         field.source_location
     )
     ir_data_utils.builder(
         field.field
-    ).existence_condition.boolean_constant.source_location.CopyFrom(
-        field.source_location
-    )
+    ).existence_condition.boolean_constant.source_location = field.source_location
     ir_data_utils.builder(field.field).existence_condition.boolean_constant.value = True
     return _List([field] + block.list)
 
@@ -1032,7 +1014,9 @@
     for field in fields.list:
         condition = ir_data_utils.builder(field.field).existence_condition
         condition.CopyFrom(expression)
-        condition.source_location.is_disjoint_from_parent = True
+        condition.source_location = condition.source_location._replace(
+            is_disjoint_from_parent=True
+        )
     return fields
 
 
@@ -1096,11 +1080,9 @@
         field.documentation.extend(field_body.list[0].documentation)
     if abbreviation.list:
         field.abbreviation.CopyFrom(abbreviation.list[0])
-    field.source_location.start.CopyFrom(location.source_location.start)
-    if field_body.source_location.HasField("end"):
-        field.source_location.end.CopyFrom(field_body.source_location.end)
-    else:
-        field.source_location.end.CopyFrom(newline.source_location.end)
+    field.source_location = parser_types.merge_source_locations(
+        location, newline, field_body
+    )
     return _FieldWithType(field=field_ir)
 
 
@@ -1121,11 +1103,9 @@
     if field_body.list:
         field.attribute.extend(field_body.list[0].attribute)
         field.documentation.extend(field_body.list[0].documentation)
-    field.source_location.start.CopyFrom(let.source_location.start)
-    if field_body.source_location.HasField("end"):
-        field.source_location.end.CopyFrom(field_body.source_location.end)
-    else:
-        field.source_location.end.CopyFrom(newline.source_location.end)
+    field.source_location = parser_types.merge_source_locations(
+        let, newline, field_body
+    )
     return _FieldWithType(field=field_ir)
 
 
@@ -1192,27 +1172,20 @@
         type_name.name.text
     )
     field.type.atomic_type.reference.source_name.extend([type_name.name])
-    field.type.atomic_type.reference.source_location.CopyFrom(type_name.source_location)
+    field.type.atomic_type.reference.source_location = type_name.source_location
     field.type.atomic_type.reference.is_local_name = True
-    field.type.atomic_type.source_location.CopyFrom(type_name.source_location)
-    field.type.source_location.CopyFrom(type_name.source_location)
+    field.type.atomic_type.source_location = type_name.source_location
+    field.type.source_location = type_name.source_location
     if abbreviation.list:
         field.abbreviation.CopyFrom(abbreviation.list[0])
-    field.source_location.start.CopyFrom(location.source_location.start)
-    ir_data_utils.builder(body.source_location).start.CopyFrom(
-        location.source_location.start
-    )
-    if body.HasField("enumeration"):
-        ir_data_utils.builder(body.enumeration).source_location.CopyFrom(
-            body.source_location
-        )
+    body.source_location = parser_types.merge_source_locations(location, body)
+    if body.has_field("enumeration"):
+        ir_data_utils.builder(body.enumeration).source_location = body.source_location
     else:
-        assert body.HasField("structure")
-        ir_data_utils.builder(body.structure).source_location.CopyFrom(
-            body.source_location
-        )
+        assert body.has_field("structure")
+        ir_data_utils.builder(body.structure).source_location = body.source_location
     ir_data_utils.builder(body).name.CopyFrom(type_name)
-    field.source_location.end.CopyFrom(body.source_location.end)
+    field.source_location = parser_types.merge_source_locations(location, body)
     subtypes = [body] + list(body.subtype)
     del body.subtype[:]
     return _FieldWithType(field=field_ir, subtypes=subtypes)
@@ -1254,11 +1227,8 @@
 @_handles('enum -> "enum" type-name ":" Comment? eol enum-body')
 def _enum(enum, name, colon, comment, newline, enum_body):
     del colon, comment, newline  # Unused.
-    ir_data_utils.builder(enum_body.enumeration).source_location.start.CopyFrom(
-        enum.source_location.start
-    )
-    ir_data_utils.builder(enum_body.enumeration).source_location.end.CopyFrom(
-        enum_body.source_location.end
+    ir_data_utils.builder(enum_body.enumeration).source_location = (
+        parser_types.merge_source_locations(enum, enum_body)
     )
     ir_data_utils.builder(enum_body).name.CopyFrom(name)
     return enum_body
@@ -1311,8 +1281,8 @@
 @_handles('external -> "external" type-name ":" Comment? eol external-body')
 def _external(external, name, colon, comment, newline, external_body):
     del colon, comment, newline  # Unused.
-    ir_data_utils.builder(external_body.source_location).start.CopyFrom(
-        external.source_location.start
+    external_body.source_location = parser_types.merge_source_locations(
+        external, external_body
     )
     if external_body.name:
         ir_data_utils.update(external_body.name, name)
@@ -1328,7 +1298,7 @@
     return ir_data.TypeDefinition(
         external=ir_data.External(
             # Set source_location here, since it won't be set automatically.
-            source_location=ir_data.Location(
+            source_location=parser_types.SourceLocation(
                 start=indent.source_location.start, end=dedent.source_location.end
             )
         ),
@@ -1366,10 +1336,10 @@
         atomic_type_source_location_end = parameters.source_location.end
     if size.list:
         base_type_source_location_end = size.source_location.end
-    base_type_location = parser_types.make_location(
+    base_type_location = parser_types.SourceLocation(
         reference.source_location.start, base_type_source_location_end
     )
-    atomic_type_location = parser_types.make_location(
+    atomic_type_location = parser_types.SourceLocation(
         reference.source_location.start, atomic_type_source_location_end
     )
     t = ir_data.Type(
@@ -1382,7 +1352,7 @@
         source_location=base_type_location,
     )
     for length in array_spec.list:
-        location = parser_types.make_location(
+        location = parser_types.SourceLocation(
             t.source_location.start, length.source_location.end
         )
         if isinstance(length, ir_data.Expression):
@@ -1524,7 +1494,7 @@
     # Note that the Void's source_location is the space between the brackets (if
     # any).
     return ir_data.Empty(
-        source_location=ir_data.Location(
+        source_location=parser_types.SourceLocation(
             start=open_bracket.source_location.end,
             end=close_bracket.source_location.start,
         )
diff --git a/compiler/front_end/module_ir_test.py b/compiler/front_end/module_ir_test.py
index ad884a8..f4faedd 100644
--- a/compiler/front_end/module_ir_test.py
+++ b/compiler/front_end/module_ir_test.py
@@ -18,6 +18,7 @@
 
 import collections
 import pkgutil
+import sys
 import unittest
 
 from compiler.front_end import module_ir
@@ -454,56 +455,35 @@
                   "function": "SUBTRACTION",
                   "function_name": {
                     "text": "-",
-                    "source_location": {
-                      "start": { "line": 8, "column": 3 },
-                      "end": { "line": 8, "column": 4 }
-                    }
+                    "source_location": "8:3-8:4"
                   },
                   "args": [
                     {
                       "constant": {
                         "value": "0",
-                        "source_location": {
-                          "start": { "line": 8, "column": 3 },
-                          "end": { "line": 8, "column": 3 }
-                        }
+                        "source_location": "8:3-8:3"
                       },
-                      "source_location": {
-                        "start": { "line": 8, "column": 3 },
-                        "end": { "line": 8, "column": 3 }
-                      }
+                      "source_location": "8:3-8:3"
                     },
                     {
                       "function": {
                         "function": "ADDITION",
                         "function_name": {
                           "text": "+",
-                          "source_location": {
-                            "start": { "line": 8, "column": 5 },
-                            "end": { "line": 8, "column": 6 }
-                          }
+                          "source_location": "8:5-8:6"
                         },
                         "args": [
                           {
                             "constant": { "value": "0" },
-                            "source_location": {
-                              "start": { "line": 8, "column": 5 },
-                              "end": { "line": 8, "column": 5 }
-                            }
+                            "source_location": "8:5-8:5"
                           },
                           {
                             "constant": { "value": "1" },
-                            "source_location": {
-                              "start": { "line": 8, "column": 6 },
-                              "end": { "line": 8, "column": 7 }
-                            }
+                            "source_location": "8:6-8:7"
                           }
                         ]
                       },
-                      "source_location": {
-                        "start": { "line": 8, "column": 4 },
-                        "end": { "line": 8, "column": 8 }
-                      }
+                      "source_location": "8:4-8:8"
                     }
                   ]
                 }
@@ -513,56 +493,35 @@
                   "function": "SUBTRACTION",
                   "function_name": {
                     "text": "-",
-                    "source_location": {
-                      "start": { "line": 8, "column": 12 },
-                      "end": { "line": 8, "column": 13 }
-                    }
+                    "source_location": "8:12-8:13"
                   },
                   "args": [
                     {
                       "constant": {
                         "value": "0",
-                        "source_location": {
-                          "start": { "line": 8, "column": 11 },
-                          "end": { "line": 8, "column": 12 }
-                        }
+                        "source_location": "8:11-8:12"
                       },
-                      "source_location": {
-                        "start": { "line": 8, "column": 11 },
-                        "end": { "line": 8, "column": 12 }
-                      }
+                      "source_location": "8:11-8:12"
                     },
                     {
                       "function": {
                         "function": "SUBTRACTION",
                         "function_name": {
                           "text": "-",
-                          "source_location": {
-                            "start": { "line": 8, "column": 14 },
-                            "end": { "line": 8, "column": 15 }
-                          }
+                          "source_location": "8:14-8:15"
                         },
                         "args": [
                           {
                             "constant": { "value": "0" },
-                            "source_location": {
-                              "start": { "line": 8, "column": 14 },
-                              "end": { "line": 8, "column": 14 }
-                            }
+                            "source_location": "8:14-8:14"
                           },
                           {
                             "constant": { "value": "10" },
-                            "source_location": {
-                              "start": { "line": 8, "column": 15 },
-                              "end": { "line": 8, "column": 17 }
-                            }
+                            "source_location": "8:15-8:17"
                           }
                         ]
                       },
-                      "source_location": {
-                        "start": { "line": 8, "column": 13 },
-                        "end": { "line": 8, "column": 18 }
-                      }
+                      "source_location": "8:13-8:18"
                     }
                   ]
                 }
@@ -642,10 +601,7 @@
                   }
                 },
                 "automatic": {
-                  "source_location": {
-                    "start": { "line": 3, "column": 16 },
-                    "end": { "line": 3, "column": 18 }
-                  }
+                  "source_location": "3:16-3:18"
                 }
               }
             },
@@ -675,17 +631,11 @@
             "location": {
               "start": {
                 "constant": { "value": "0" },
-                "source_location": {
-                  "start": { "line": 3, "column": 3 },
-                  "end": { "line": 3, "column": 4 }
-                }
+                "source_location": "3:3-3:4"
               },
               "size": {
                 "constant": { "value": "1" },
-                "source_location": {
-                  "start": { "line": 3, "column": 9 },
-                  "end": { "line": 3, "column": 10 }
-                }
+                "source_location": "3:9-3:10"
               }
             }
           },
@@ -1825,28 +1775,16 @@
     {
       "file_name": {
         "text": "",
-        "source_location": {
-          "start": { "line": 1, "column": 1 },
-          "end": { "line": 1, "column": 1 }
-        }
+        "source_location": "1:1-1:1"
       },
       "local_name": {
         "text": "",
-        "source_location": {
-          "start": { "line": 1, "column": 1 },
-          "end": { "line": 1, "column": 1 }
-        }
+        "source_location": "1:1-1:1"
       },
-      "source_location": {
-        "start": { "line": 1, "column": 1 },
-        "end": { "line": 1, "column": 1 }
-      }
+      "source_location": "1:1-1:1"
     }
   ],
-  "source_location": {
-    "start": { "line": 1, "column": 1 },
-    "end": { "line": 1, "column": 1 }
-  }
+  "source_location": "1:1-1:1"
 }
 
 ===
@@ -3547,15 +3485,9 @@
                 "reference": { "source_name": [ { "text": "UInt" } ] }
               },
               "size_in_bits": {
-                "source_location": {
-                  "start": { "line": 3, "column": 15 },
-                  "end": { "line": 3, "column": 18 }
-                }
+                "source_location": "3:15-3:18"
               },
-              "source_location": {
-                "start": { "line": 3, "column": 11 },
-                "end": { "line": 3, "column": 18 }
-              }
+              "source_location": "3:11-3:18"
             },
             "name": { "name": { "text": "field" } }
           }
@@ -4017,68 +3949,28 @@
     Returns:
       A list of error messages, or an empty list if no errors.
     """
-    if source_location.is_disjoint_from_parent:
-        # If source_location.is_disjoint_from_parent, then this source_location is
-        # allowed to be outside of the parent's source_location.
-        return []
-
     result = []
     start = None
     end = None
-    if not source_location.HasField("start"):
+    if not source_location.start:
         result.append("{}.start missing".format(path))
     else:
         start = source_location.start
-    if not source_location.HasField("end"):
+    if not source_location.end:
         result.append("{}.end missing".format(path))
     else:
         end = source_location.end
 
-    if start and end:
-        if start.HasField("line") and end.HasField("line"):
-            if start.line > end.line:
-                result.append(
-                    "{}.start.line > {}.end.line ({} vs {})".format(
-                        path, path, start.line, end.line
-                    )
-                )
-            elif start.line == end.line:
-                if (
-                    start.HasField("column")
-                    and end.HasField("column")
-                    and start.column > end.column
-                ):
-                    result.append(
-                        "{}.start.column > {}.end.column ({} vs {})".format(
-                            path, path, start.column, end.column
-                        )
-                    )
+    if not source_location.is_disjoint_from_parent:
+        # If source_location.is_disjoint_from_parent, then this source_location
+        # is allowed to be outside of the parent's source_location.
+        if min_start and start:
+            if min_start > start:
+                result.append("{}.start before parent start".format(path))
 
-    for name, field in (("start", start), ("end", end)):
-        if not field:
-            continue
-        if field.HasField("line"):
-            if field.line <= 0:
-                result.append("{}.{}.line <= 0 ({})".format(path, name, field.line))
-        else:
-            result.append("{}.{}.line missing".format(path, name))
-        if field.HasField("column"):
-            if field.column <= 0:
-                result.append("{}.{}.column <= 0 ({})".format(path, name, field.column))
-        else:
-            result.append("{}.{}.column missing".format(path, name))
-
-    if min_start and start:
-        if min_start.line > start.line or (
-            min_start.line == start.line and min_start.column > start.column
-        ):
-            result.append("{}.start before parent start".format(path))
-
-    if max_end and end:
-        if max_end.line < end.line or (
-            max_end.line == end.line and max_end.column < end.column
-        ):
-            result.append("{}.end after parent end".format(path))
+        if max_end and end:
+            if max_end < end:
+                result.append("{}.end after parent end".format(path))
 
     return result
 
@@ -4104,7 +3996,7 @@
     child_end = None
     # Only check the source_location value if this proto message actually has a
     # source_location field.
-    if proto.HasField("source_location"):
+    if proto.has_field("source_location"):
         errors.extend(
             _check_source_location(
                 proto.source_location, path + "source_location", min_start, max_end
@@ -4116,7 +4008,7 @@
     for name, spec in ir_data_fields.field_specs(proto).items():
         if name == "source_location":
             continue
-        if not proto.HasField(name):
+        if not proto.has_field(name):
             continue
         field_path = "{}{}".format(path, name)
         if spec.is_dataclass:
@@ -4166,6 +4058,18 @@
             parse_result = parser.parse_module(tokenizer.tokenize(example, "")[0])
             self.assertFalse(parse_result.error)
 
+    def test_long_input(self):
+        """Checks that very long inputs do not hit the Python recursion limit."""
+        emb = ["enum Test:\n"]
+        # Enough entities to blow through the default recursion limit and the
+        # bumped limit that was previously in place.
+        for i in range(max(sys.getrecursionlimit(), 16 * 1024) * 2):
+            emb.append(f"  VALUE_{i} = {i}\n")
+        parse_result = parser.parse_module(
+            tokenizer.tokenize("".join(emb), "long.emb")[0]
+        )
+        module_ir.build_ir(parse_result.parse_tree)
+
 
 def _make_superset_tests():
 
diff --git a/compiler/front_end/symbol_resolver.py b/compiler/front_end/symbol_resolver.py
index 0590b0d..9f46ff3 100644
--- a/compiler/front_end/symbol_resolver.py
+++ b/compiler/front_end/symbol_resolver.py
@@ -24,6 +24,7 @@
 from compiler.util import ir_data
 from compiler.util import ir_data_utils
 from compiler.util import ir_util
+from compiler.util import parser_types
 from compiler.util import traverse_ir
 
 # TODO(bolms): Symbol resolution raises an exception at the first error, but
@@ -160,14 +161,14 @@
     new_scope = _add_name_to_scope_and_normalize(
         field.name, scope, _Scope.LOCAL, errors
     )
-    if field.HasField("abbreviation"):
+    if field.has_field("abbreviation"):
         _add_name_to_scope(
             field.abbreviation, scope, new_scope.canonical_name, _Scope.PRIVATE, errors
         )
 
     value_builtin_name = ir_data.Word(
         text="this",
-        source_location=ir_data.Location(is_synthetic=True),
+        source_location=parser_types.SourceLocation(is_synthetic=True),
     )
     # In "inside field" scope, the name `this` maps back to the field itself.
     # This is important for attributes like `[requires]`.
@@ -330,7 +331,7 @@
     reference, table, current_scope, visible_scopes, source_file_name, errors
 ):
     """Sets the canonical name of the given reference."""
-    if reference.HasField("canonical_name"):
+    if reference.has_field("canonical_name"):
         # This reference has already been resolved by the _resolve_field_reference
         # pass.
         return
@@ -452,7 +453,7 @@
 
 def _resolve_field_reference(field_reference, source_file_name, errors, ir):
     """Resolves the References inside of a FieldReference."""
-    if field_reference.path[-1].HasField("canonical_name"):
+    if field_reference.path[-1].has_field("canonical_name"):
         # Already done.
         return
     previous_field = ir_util.find_object_or_none(field_reference.path[0], ir)
@@ -475,7 +476,7 @@
                 # field, then bail.  Otherwise we get a cascade of errors, where an
                 # error in `x` leads to errors in anything trying to reach a member of
                 # `x`.
-                if not previous_field.read_transform.field_reference.path[-1].HasField(
+                if not previous_field.read_transform.field_reference.path[-1].has_field(
                     "canonical_name"
                 ):
                     return
diff --git a/compiler/front_end/symbol_resolver_test.py b/compiler/front_end/symbol_resolver_test.py
index ddf7783..4a50feb 100644
--- a/compiler/front_end/symbol_resolver_test.py
+++ b/compiler/front_end/symbol_resolver_test.py
@@ -159,7 +159,7 @@
         self.assertEqual([], symbol_resolver.resolve_symbols(ir))
         struct_ir = ir.module[0].type[6].structure
         size_ir = struct_ir.field[0].location.size
-        self.assertTrue(size_ir.HasField("field_reference"))
+        self.assertTrue(size_ir.has_field("field_reference"))
         self.assertEqual(
             size_ir.field_reference.path[0].canonical_name.object_path,
             ["UsesParameter", "x"],
@@ -552,8 +552,8 @@
         struct1_byte_field = struct1.structure.field[4]
         inner_bits = struct1.subtype[0]
         inner_enum = struct1.subtype[1]
-        self.assertTrue(inner_bits.HasField("structure"))
-        self.assertTrue(inner_enum.HasField("enumeration"))
+        self.assertTrue(inner_bits.has_field("structure"))
+        self.assertTrue(inner_enum.has_field("enumeration"))
         self.assertTrue(inner_bits.name.is_anonymous)
         self.assertFalse(inner_enum.name.is_anonymous)
         self.assertEqual(
diff --git a/compiler/front_end/synthetics.py b/compiler/front_end/synthetics.py
index f55e32f..dc23177 100644
--- a/compiler/front_end/synthetics.py
+++ b/compiler/front_end/synthetics.py
@@ -28,7 +28,9 @@
     if not isinstance(proto, ir_data.Message):
         return
     if hasattr(proto, "source_location"):
-        ir_data_utils.builder(proto).source_location.is_synthetic = True
+        proto.source_location = ir_data_utils.reader(proto).source_location._replace(
+            is_synthetic=True
+        )
     for spec, value in ir_data_utils.get_set_fields(proto):
         if spec.name != "source_location" and spec.is_dataclass:
             if spec.is_sequence:
@@ -140,7 +142,7 @@
                 existence_condition=new_existence_condition,
                 name=ir_data_utils.copy(subfield.name),
             )
-            if subfield.HasField("abbreviation"):
+            if subfield.has_field("abbreviation"):
                 ir_data_utils.builder(new_alias).abbreviation.CopyFrom(
                     subfield.abbreviation
                 )
@@ -151,7 +153,7 @@
             # original field's name(s) as synthetic, to avoid duplicate error
             # messages.
             _mark_as_synthetic(subfield.name)
-            if subfield.HasField("abbreviation"):
+            if subfield.has_field("abbreviation"):
                 _mark_as_synthetic(subfield.abbreviation)
     del structure.field[:]
     structure.field.extend(new_fields)
@@ -237,7 +239,7 @@
     expression_ir, last_location, source_file_name, errors
 ):
     """Replaces the `$next` keyword in an expression."""
-    if not expression_ir.HasField("builtin_reference"):
+    if not expression_ir.has_field("builtin_reference"):
         return
     if (
         ir_data_utils.reader(
@@ -263,12 +265,12 @@
     expression.CopyFrom(_NEXT_KEYWORD_REPLACEMENT_EXPRESSION)
     expression.function.args[0].CopyFrom(last_location.start)
     expression.function.args[1].CopyFrom(last_location.size)
-    expression.source_location.CopyFrom(original_location)
+    expression.source_location = original_location
     _mark_as_synthetic(expression.function)
 
 
 def _check_for_bad_next_keyword_in_size(expression, source_file_name, errors):
-    if not expression.HasField("builtin_reference"):
+    if not expression.has_field("builtin_reference"):
         return
     if expression.builtin_reference.canonical_name.object_path[0] != "$next":
         return
diff --git a/compiler/front_end/synthetics_test.py b/compiler/front_end/synthetics_test.py
index ac8e671..7e71bb9 100644
--- a/compiler/front_end/synthetics_test.py
+++ b/compiler/front_end/synthetics_test.py
@@ -64,12 +64,12 @@
         self.assertEqual([], synthetics.desugar(ir))
         structure = ir.module[0].type[0].structure
         # The first field should be the anonymous bits structure.
-        self.assertTrue(structure.field[0].HasField("location"))
+        self.assertTrue(structure.field[0].has_field("location"))
         # Then the aliases generated for those structures.
         self.assertEqual("bar", structure.field[1].name.name.text)
         self.assertEqual("uint", structure.field[2].name.name.text)
         # Then the second anonymous bits.
-        self.assertTrue(structure.field[3].HasField("location"))
+        self.assertTrue(structure.field[3].has_field("location"))
         # Then the alias from the second anonymous bits.
         self.assertEqual("nested_bits", structure.field[4].name.name.text)
 
@@ -145,7 +145,7 @@
         self.assertEqual([], synthetics.desugar(ir))
         bar_alias = ir.module[0].type[0].structure.field[1]
         baz_alias = ir.module[0].type[0].structure.field[2]
-        self.assertFalse(bar_alias.HasField("abbreviation"))
+        self.assertFalse(bar_alias.has_field("abbreviation"))
         self.assertEqual("qux", baz_alias.abbreviation.text)
 
     def test_anonymous_bits_sets_correct_is_synthetic(self):
@@ -156,9 +156,9 @@
         bits_field = ir.module[0].type[0].subtype[0].structure.field[0]
         alias_field = ir.module[0].type[0].structure.field[1]
         self.assertFalse(alias_field.name.source_location.is_synthetic)
-        self.assertTrue(alias_field.HasField("abbreviation"))
+        self.assertTrue(alias_field.has_field("abbreviation"))
         self.assertFalse(alias_field.abbreviation.source_location.is_synthetic)
-        self.assertTrue(alias_field.HasField("read_transform"))
+        self.assertTrue(alias_field.has_field("read_transform"))
         read_alias = alias_field.read_transform
         self.assertTrue(read_alias.source_location.is_synthetic)
         self.assertTrue(read_alias.field_reference.path[0].source_location.is_synthetic)
@@ -265,7 +265,7 @@
         )
         self.assertEqual([], synthetics.desugar(ir))
         offset_of_b = ir.module[0].type[0].structure.field[1].location.start
-        self.assertTrue(offset_of_b.HasField("function"))
+        self.assertTrue(offset_of_b.has_field("function"))
         self.assertEqual(
             offset_of_b.function.function, ir_data.FunctionMapping.ADDITION
         )
diff --git a/compiler/front_end/tokenizer.py b/compiler/front_end/tokenizer.py
index d537dca..7a593aa 100644
--- a/compiler/front_end/tokenizer.py
+++ b/compiler/front_end/tokenizer.py
@@ -71,7 +71,7 @@
                 parser_types.Token(
                     '"\\n"',
                     "\n",
-                    parser_types.make_location(
+                    parser_types.SourceLocation(
                         (line_number, len(line) + 1), (line_number, len(line) + 1)
                     ),
                 )
@@ -92,7 +92,7 @@
                 parser_types.Token(
                     "Indent",
                     leading_whitespace[len(indent_stack[-1]) :],
-                    parser_types.make_location(
+                    parser_types.SourceLocation(
                         (line_number, len(indent_stack[-1]) + 1),
                         (line_number, len(leading_whitespace) + 1),
                     ),
@@ -110,7 +110,7 @@
                     parser_types.Token(
                         "Dedent",
                         "",
-                        parser_types.make_location(
+                        parser_types.SourceLocation(
                             (line_number, len(leading_whitespace) + 1),
                             (line_number, len(leading_whitespace) + 1),
                         ),
@@ -122,7 +122,7 @@
                     [
                         error.error(
                             file_name,
-                            parser_types.make_location(
+                            parser_types.SourceLocation(
                                 (line_number, 1),
                                 (line_number, len(leading_whitespace) + 1),
                             ),
@@ -138,7 +138,7 @@
             parser_types.Token(
                 '"\\n"',
                 "\n",
-                parser_types.make_location(
+                parser_types.SourceLocation(
                     (line_number, len(line) + 1), (line_number, len(line) + 1)
                 ),
             )
@@ -148,7 +148,7 @@
             parser_types.Token(
                 "Dedent",
                 "",
-                parser_types.make_location((line_number + 1, 1), (line_number + 1, 1)),
+                parser_types.SourceLocation((line_number + 1, 1), (line_number + 1, 1)),
             )
         )
     return tokens, []
@@ -250,7 +250,7 @@
                 [
                     error.error(
                         file_name,
-                        parser_types.make_location(
+                        parser_types.SourceLocation(
                             (line_number, offset + 1), (line_number, offset + 2)
                         ),
                         "Unrecognized token",
@@ -262,7 +262,7 @@
                 parser_types.Token(
                     best_candidate_symbol,
                     best_candidate,
-                    parser_types.make_location(
+                    parser_types.SourceLocation(
                         (line_number, offset + 1),
                         (line_number, offset + len(best_candidate) + 1),
                     ),
diff --git a/compiler/front_end/tokenizer_test.py b/compiler/front_end/tokenizer_test.py
index 6a301e6..f858348 100644
--- a/compiler/front_end/tokenizer_test.py
+++ b/compiler/front_end/tokenizer_test.py
@@ -37,7 +37,7 @@
                 [
                     error.error(
                         "file",
-                        parser_types.make_location((2, 1), (2, 2)),
+                        parser_types.SourceLocation((2, 1), (2, 2)),
                         "Bad indentation",
                     )
                 ]
@@ -53,7 +53,7 @@
                 [
                     error.error(
                         "file",
-                        parser_types.make_location((2, 1), (2, 2)),
+                        parser_types.SourceLocation((2, 1), (2, 2)),
                         "Bad indentation",
                     )
                 ]
@@ -69,7 +69,7 @@
                 [
                     error.error(
                         "file",
-                        parser_types.make_location((2, 1), (2, 2)),
+                        parser_types.SourceLocation((2, 1), (2, 2)),
                         "Bad indentation",
                     )
                 ]
@@ -85,7 +85,7 @@
                 [
                     error.error(
                         "file",
-                        parser_types.make_location((2, 1), (2, 2)),
+                        parser_types.SourceLocation((2, 1), (2, 2)),
                         "Bad indentation",
                     )
                 ]
@@ -101,7 +101,7 @@
                 [
                     error.error(
                         "file",
-                        parser_types.make_location((4, 1), (4, 2)),
+                        parser_types.SourceLocation((4, 1), (4, 2)),
                         "Bad indentation",
                     )
                 ]
@@ -117,7 +117,7 @@
                 [
                     error.error(
                         "name",
-                        parser_types.make_location((1, 5), (1, 6)),
+                        parser_types.SourceLocation((1, 5), (1, 6)),
                         "Unrecognized token",
                     )
                 ]
@@ -354,7 +354,7 @@
                     [
                         error.error(
                             "name",
-                            parser_types.make_location((1, 1), (1, 2)),
+                            parser_types.SourceLocation((1, 1), (1, 2)),
                             "Unrecognized token",
                         )
                     ]
@@ -382,7 +382,7 @@
                     [
                         error.error(
                             "name",
-                            parser_types.make_location((1, 1), (1, 2)),
+                            parser_types.SourceLocation((1, 1), (1, 2)),
                             "Unrecognized token",
                         )
                     ]
@@ -482,10 +482,7 @@
 
         def test_case(self):
             self.assertEqual(
-                [
-                    parser_types.format_location(l.source_location)
-                    for l in tokenizer.tokenize(case, "file")[0]
-                ],
+                [str(l.source_location) for l in tokenizer.tokenize(case, "file")[0]],
                 cases[case],
             )
 
diff --git a/compiler/front_end/type_check.py b/compiler/front_end/type_check.py
index ce4155d..119d8cf 100644
--- a/compiler/front_end/type_check.py
+++ b/compiler/front_end/type_check.py
@@ -286,7 +286,7 @@
         )
         ir_data_utils.builder(expression).type.CopyFrom(field.read_transform.type)
         return
-    if not field.type.HasField("atomic_type"):
+    if not field.type.has_field("atomic_type"):
         ir_data_utils.builder(expression).type.opaque.CopyFrom(ir_data.OpaqueType())
     else:
         _set_expression_type_from_physical_type_reference(
@@ -313,7 +313,7 @@
     elif tuple(type_definition.name.canonical_name.object_path) == ("Flag",):
         # This is a hack: the Flag type should say that it is a boolean.
         return ir_data.ExpressionType(boolean=ir_data.BooleanType())
-    elif type_definition.HasField("enumeration"):
+    elif type_definition.has_field("enumeration"):
         return ir_data.ExpressionType(
             enumeration=ir_data.EnumType(
                 name=ir_data.Reference(
diff --git a/compiler/front_end/type_check_test.py b/compiler/front_end/type_check_test.py
index 766f9e8..dfa5663 100644
--- a/compiler/front_end/type_check_test.py
+++ b/compiler/front_end/type_check_test.py
@@ -410,7 +410,7 @@
         expression = ir.module[0].type[0].structure.field[1].location.size
         self.assertEqual([], error.filter_errors(type_check.annotate_types(ir)))
         self.assertEqual("enumeration", expression.type.which_type)
-        self.assertFalse(expression.type.enumeration.HasField("value"))
+        self.assertFalse(expression.type.enumeration.has_field("value"))
         self.assertEqual(
             "m.emb", expression.type.enumeration.name.canonical_name.module_file
         )
diff --git a/compiler/front_end/write_inference.py b/compiler/front_end/write_inference.py
index bd4e2ba..d50b62b 100644
--- a/compiler/front_end/write_inference.py
+++ b/compiler/front_end/write_inference.py
@@ -19,6 +19,7 @@
 from compiler.util import ir_data
 from compiler.util import ir_data_utils
 from compiler.util import ir_util
+from compiler.util import parser_types
 from compiler.util import traverse_ir
 
 
@@ -118,13 +119,13 @@
             source_name=[
                 ir_data.Word(
                     text="$logical_value",
-                    source_location=ir_data.Location(is_synthetic=True),
+                    source_location=parser_types.SourceLocation(is_synthetic=True),
                 )
             ],
-            source_location=ir_data.Location(is_synthetic=True),
+            source_location=parser_types.SourceLocation(is_synthetic=True),
         ),
         type=expression.type,
-        source_location=ir_data.Location(is_synthetic=True),
+        source_location=parser_types.SourceLocation(is_synthetic=True),
     )
 
     # This loop essentially starts with:
@@ -212,7 +213,7 @@
     Returns:
       None
     """
-    if field.HasField("write_method"):
+    if field.has_field("write_method"):
         # Do not recompute anything.
         return
 
diff --git a/compiler/front_end/write_inference_test.py b/compiler/front_end/write_inference_test.py
index f4ea8bf..3db22f0 100644
--- a/compiler/front_end/write_inference_test.py
+++ b/compiler/front_end/write_inference_test.py
@@ -46,7 +46,7 @@
         ir = self._make_ir("struct Foo:\n" "  let x = y\n" "  0 [+1]  UInt  y\n")
         self.assertEqual([], write_inference.set_write_methods(ir))
         field = ir.module[0].type[0].structure.field[0]
-        self.assertTrue(field.write_method.HasField("alias"))
+        self.assertTrue(field.write_method.has_field("alias"))
         self.assertEqual(
             "y", field.write_method.alias.path[0].canonical_name.object_path[-1]
         )
@@ -57,7 +57,7 @@
         )
         self.assertEqual([], write_inference.set_write_methods(ir))
         field = ir.module[0].type[0].structure.field[0]
-        self.assertTrue(field.write_method.HasField("alias"))
+        self.assertTrue(field.write_method.has_field("alias"))
         self.assertEqual(
             "z", field.write_method.alias.path[0].canonical_name.object_path[-1]
         )
diff --git a/compiler/util/BUILD b/compiler/util/BUILD
index ab53344..4a444fd 100644
--- a/compiler/util/BUILD
+++ b/compiler/util/BUILD
@@ -28,13 +28,18 @@
         "ir_data_fields.py",
         "ir_data_utils.py",
     ],
-    deps = [],
+    deps = [
+        ":parser_types",
+    ],
 )
 
 py_test(
     name = "ir_data_fields_test",
     srcs = ["ir_data_fields_test.py"],
-    deps = [":ir_data"],
+    deps = [
+        ":ir_data",
+        ":parser_types",
+    ],
 )
 
 py_test(
@@ -136,9 +141,7 @@
 py_library(
     name = "parser_types",
     srcs = ["parser_types.py"],
-    deps = [
-        ":ir_data",
-    ],
+    deps = [],
 )
 
 py_test(
@@ -152,6 +155,14 @@
 )
 
 py_library(
+    name = "parser_util",
+    srcs = ["parser_util.py"],
+    deps = [
+        ":parser_types",
+    ],
+)
+
+py_library(
     name = "error",
     srcs = [
         "error.py",
diff --git a/compiler/util/attribute_util.py b/compiler/util/attribute_util.py
index d20f191..506459c 100644
--- a/compiler/util/attribute_util.py
+++ b/compiler/util/attribute_util.py
@@ -40,7 +40,7 @@
 # Attribute type checkers
 def _is_constant_boolean(attr, module_source_file):
     """Checks if the given attr is a constant boolean."""
-    if not attr.value.expression.type.boolean.HasField("value"):
+    if not attr.value.expression.type.boolean.has_field("value"):
         return [
             [
                 error.error(
@@ -75,7 +75,7 @@
 def _is_constant_integer(attr, module_source_file):
     """Checks if the given attr is an integer constant expression."""
     if (
-        not attr.value.HasField("expression")
+        not attr.value.has_field("expression")
         or attr.value.expression.type.which_type != "integer"
     ):
         return [
@@ -106,7 +106,7 @@
 
 def _is_string(attr, module_source_file):
     """Checks if the given attr is a string."""
-    if not attr.value.HasField("string_constant"):
+    if not attr.value.has_field("string_constant"):
         return [
             [
                 error.error(
@@ -217,7 +217,7 @@
         )
 
     def check_type_definition(type_definition, source_file_name, errors):
-        if type_definition.HasField("structure"):
+        if type_definition.has_field("structure"):
             if type_definition.addressable_unit == ir_data.AddressableUnit.BYTE:
                 errors.extend(
                     _check_attributes(
@@ -244,7 +244,7 @@
                 assert False, "Unexpected addressable_unit '{}'".format(
                     type_definition.addressable_unit
                 )
-        elif type_definition.HasField("enumeration"):
+        elif type_definition.has_field("enumeration"):
             errors.extend(
                 _check_attributes(
                     type_definition.attribute,
@@ -255,7 +255,7 @@
                     source_file_name,
                 )
             )
-        elif type_definition.HasField("external"):
+        elif type_definition.has_field("external"):
             errors.extend(
                 _check_attributes(
                     type_definition.attribute,
diff --git a/compiler/util/error.py b/compiler/util/error.py
index c580520..93d7a11 100644
--- a/compiler/util/error.py
+++ b/compiler/util/error.py
@@ -36,7 +36,6 @@
     ]
 """
 
-from compiler.util import ir_data_utils
 from compiler.util import parser_types
 
 # Error levels; represented by the strings that will be included in messages.
@@ -67,26 +66,25 @@
 RESET = "\033[0m"
 
 
-def _copy(location):
-    location = ir_data_utils.copy(location)
+def location_or_default(location):
     if not location:
-        location = parser_types.make_location((0, 0), (0, 0))
+        return parser_types.SourceLocation((0, 0), (0, 0))
     return location
 
 
 def error(source_file, location, message):
     """Returns an object representing an error message."""
-    return _Message(source_file, _copy(location), ERROR, message)
+    return _Message(source_file, location_or_default(location), ERROR, message)
 
 
 def warn(source_file, location, message):
     """Returns an object representing a warning."""
-    return _Message(source_file, _copy(location), WARNING, message)
+    return _Message(source_file, location_or_default(location), WARNING, message)
 
 
 def note(source_file, location, message):
     """Returns and object representing an informational note."""
-    return _Message(source_file, _copy(location), NOTE, message)
+    return _Message(source_file, location_or_default(location), NOTE, message)
 
 
 class _Message(object):
@@ -139,7 +137,7 @@
         if self.location.is_synthetic:
             pos = "[compiler bug]"
         else:
-            pos = parser_types.format_position(self.location.start)
+            pos = str(self.location.start)
         source_name = self.source_file or "[prelude]"
         if not self.location.is_synthetic and self.source_file in source_code:
             source_lines = source_code[self.source_file].splitlines()
@@ -174,20 +172,7 @@
         return result
 
     def __repr__(self):
-        return (
-            "Message({source_file!r}, make_location(({start_line!r}, "
-            "{start_column!r}), ({end_line!r}, {end_column!r}), "
-            "{is_synthetic!r}), {severity!r}, {message!r})"
-        ).format(
-            source_file=self.source_file,
-            start_line=self.location.start.line,
-            start_column=self.location.start.column,
-            end_line=self.location.end.line,
-            end_column=self.location.end.column,
-            is_synthetic=self.location.is_synthetic,
-            severity=self.severity,
-            message=self.message,
-        )
+        return f"Message({repr(self.source_file)}, {repr(self.location)}, {repr(self.severity)}, {repr(self.message)})"
 
     def __eq__(self, other):
         return (
diff --git a/compiler/util/error_test.py b/compiler/util/error_test.py
index 45f9920..169163d 100644
--- a/compiler/util/error_test.py
+++ b/compiler/util/error_test.py
@@ -25,12 +25,12 @@
 
     def test_error(self):
         error_message = error.error(
-            "foo.emb", parser_types.make_location((3, 4), (3, 6)), "Bad thing"
+            "foo.emb", parser_types.SourceLocation((3, 4), (3, 6)), "Bad thing"
         )
         self.assertEqual("foo.emb", error_message.source_file)
         self.assertEqual(error.ERROR, error_message.severity)
         self.assertEqual(
-            parser_types.make_location((3, 4), (3, 6)), error_message.location
+            parser_types.SourceLocation((3, 4), (3, 6)), error_message.location
         )
         self.assertEqual("Bad thing", error_message.message)
         sourceless_format = error_message.format({})
@@ -40,7 +40,7 @@
         )
         self.assertEqual(
             [
-                (error.BOLD, "foo.emb:3:4: "),  # Location
+                (error.BOLD, "foo.emb:3:4: "),  # SourceLocation
                 (error.BRIGHT_RED, "error: "),  # Severity
                 (error.BOLD, "Bad thing"),  # Message
             ],
@@ -52,7 +52,7 @@
         )
         self.assertEqual(
             [
-                (error.BOLD, "foo.emb:3:4: "),  # Location
+                (error.BOLD, "foo.emb:3:4: "),  # SourceLocation
                 (error.BRIGHT_RED, "error: "),  # Severity
                 (error.BOLD, "Bad thing\n"),  # Message
                 (error.WHITE, "abcdefghijklm\n"),  # Source snippet
@@ -63,7 +63,9 @@
 
     def test_synthetic_error(self):
         error_message = error.error(
-            "foo.emb", parser_types.make_location((3, 4), (3, 6), True), "Bad thing"
+            "foo.emb",
+            parser_types.SourceLocation((3, 4), (3, 6), is_synthetic=True),
+            "Bad thing",
         )
         sourceless_format = error_message.format({})
         sourced_format = error_message.format({"foo.emb": "\n\nabcdefghijklm"})
@@ -73,7 +75,7 @@
         )
         self.assertEqual(
             [
-                (error.BOLD, "foo.emb:[compiler bug]: "),  # Location
+                (error.BOLD, "foo.emb:[compiler bug]: "),  # SourceLocation
                 (error.BRIGHT_RED, "error: "),  # Severity
                 (error.BOLD, "Bad thing"),  # Message
             ],
@@ -85,7 +87,7 @@
         )
         self.assertEqual(
             [
-                (error.BOLD, "foo.emb:[compiler bug]: "),  # Location
+                (error.BOLD, "foo.emb:[compiler bug]: "),  # SourceLocation
                 (error.BRIGHT_RED, "error: "),  # Severity
                 (error.BOLD, "Bad thing"),  # Message
             ],
@@ -94,12 +96,12 @@
 
     def test_prelude_as_file_name(self):
         error_message = error.error(
-            "", parser_types.make_location((3, 4), (3, 6)), "Bad thing"
+            "", parser_types.SourceLocation((3, 4), (3, 6)), "Bad thing"
         )
         self.assertEqual("", error_message.source_file)
         self.assertEqual(error.ERROR, error_message.severity)
         self.assertEqual(
-            parser_types.make_location((3, 4), (3, 6)), error_message.location
+            parser_types.SourceLocation((3, 4), (3, 6)), error_message.location
         )
         self.assertEqual("Bad thing", error_message.message)
         sourceless_format = error_message.format({})
@@ -110,7 +112,7 @@
         )
         self.assertEqual(
             [
-                (error.BOLD, "[prelude]:3:4: "),  # Location
+                (error.BOLD, "[prelude]:3:4: "),  # SourceLocation
                 (error.BRIGHT_RED, "error: "),  # Severity
                 (error.BOLD, "Bad thing"),  # Message
             ],
@@ -122,7 +124,7 @@
         )
         self.assertEqual(
             [
-                (error.BOLD, "[prelude]:3:4: "),  # Location
+                (error.BOLD, "[prelude]:3:4: "),  # SourceLocation
                 (error.BRIGHT_RED, "error: "),  # Severity
                 (error.BOLD, "Bad thing\n"),  # Message
                 (error.WHITE, "abcdefghijklm\n"),  # Source snippet
@@ -133,12 +135,12 @@
 
     def test_multiline_error_source(self):
         error_message = error.error(
-            "foo.emb", parser_types.make_location((3, 4), (4, 6)), "Bad thing"
+            "foo.emb", parser_types.SourceLocation((3, 4), (4, 6)), "Bad thing"
         )
         self.assertEqual("foo.emb", error_message.source_file)
         self.assertEqual(error.ERROR, error_message.severity)
         self.assertEqual(
-            parser_types.make_location((3, 4), (4, 6)), error_message.location
+            parser_types.SourceLocation((3, 4), (4, 6)), error_message.location
         )
         self.assertEqual("Bad thing", error_message.message)
         sourceless_format = error_message.format({})
@@ -150,7 +152,7 @@
         )
         self.assertEqual(
             [
-                (error.BOLD, "foo.emb:3:4: "),  # Location
+                (error.BOLD, "foo.emb:3:4: "),  # SourceLocation
                 (error.BRIGHT_RED, "error: "),  # Severity
                 (error.BOLD, "Bad thing"),  # Message
             ],
@@ -162,7 +164,7 @@
         )
         self.assertEqual(
             [
-                (error.BOLD, "foo.emb:3:4: "),  # Location
+                (error.BOLD, "foo.emb:3:4: "),  # SourceLocation
                 (error.BRIGHT_RED, "error: "),  # Severity
                 (error.BOLD, "Bad thing\n"),  # Message
                 (error.WHITE, "abcdefghijklm\n"),  # Source snippet
@@ -174,13 +176,13 @@
     def test_multiline_error(self):
         error_message = error.error(
             "foo.emb",
-            parser_types.make_location((3, 4), (3, 6)),
+            parser_types.SourceLocation((3, 4), (3, 6)),
             "Bad thing\nSome explanation\nMore explanation",
         )
         self.assertEqual("foo.emb", error_message.source_file)
         self.assertEqual(error.ERROR, error_message.severity)
         self.assertEqual(
-            parser_types.make_location((3, 4), (3, 6)), error_message.location
+            parser_types.SourceLocation((3, 4), (3, 6)), error_message.location
         )
         self.assertEqual(
             "Bad thing\nSome explanation\nMore explanation", error_message.message
@@ -197,13 +199,13 @@
         )
         self.assertEqual(
             [
-                (error.BOLD, "foo.emb:3:4: "),  # Location
+                (error.BOLD, "foo.emb:3:4: "),  # SourceLocation
                 (error.BRIGHT_RED, "error: "),  # Severity
                 (error.BOLD, "Bad thing\n"),  # Message
-                (error.BOLD, "foo.emb:3:4: "),  # Location, line 2
+                (error.BOLD, "foo.emb:3:4: "),  # SourceLocation, line 2
                 (error.WHITE, "note: "),  # "Note" severity, line 2
                 (error.WHITE, "Some explanation\n"),  # Message, line 2
-                (error.BOLD, "foo.emb:3:4: "),  # Location, line 3
+                (error.BOLD, "foo.emb:3:4: "),  # SourceLocation, line 3
                 (error.WHITE, "note: "),  # "Note" severity, line 3
                 (error.WHITE, "More explanation"),  # Message, line 3
             ],
@@ -219,13 +221,13 @@
         )
         self.assertEqual(
             [
-                (error.BOLD, "foo.emb:3:4: "),  # Location
+                (error.BOLD, "foo.emb:3:4: "),  # SourceLocation
                 (error.BRIGHT_RED, "error: "),  # Severity
                 (error.BOLD, "Bad thing\n"),  # Message
-                (error.BOLD, "foo.emb:3:4: "),  # Location, line 2
+                (error.BOLD, "foo.emb:3:4: "),  # SourceLocation, line 2
                 (error.WHITE, "note: "),  # "Note" severity, line 2
                 (error.WHITE, "Some explanation\n"),  # Message, line 2
-                (error.BOLD, "foo.emb:3:4: "),  # Location, line 3
+                (error.BOLD, "foo.emb:3:4: "),  # SourceLocation, line 3
                 (error.WHITE, "note: "),  # "Note" severity, line 3
                 (error.WHITE, "More explanation\n"),  # Message, line 3
                 (error.WHITE, "abcdefghijklm\n"),  # Source snippet
@@ -236,12 +238,12 @@
 
     def test_warn(self):
         warning_message = error.warn(
-            "foo.emb", parser_types.make_location((3, 4), (3, 6)), "Not good thing"
+            "foo.emb", parser_types.SourceLocation((3, 4), (3, 6)), "Not good thing"
         )
         self.assertEqual("foo.emb", warning_message.source_file)
         self.assertEqual(error.WARNING, warning_message.severity)
         self.assertEqual(
-            parser_types.make_location((3, 4), (3, 6)), warning_message.location
+            parser_types.SourceLocation((3, 4), (3, 6)), warning_message.location
         )
         self.assertEqual("Not good thing", warning_message.message)
         sourced_format = warning_message.format({"foo.emb": "\n\nabcdefghijklm"})
@@ -251,7 +253,7 @@
         )
         self.assertEqual(
             [
-                (error.BOLD, "foo.emb:3:4: "),  # Location
+                (error.BOLD, "foo.emb:3:4: "),  # SourceLocation
                 (error.BRIGHT_YELLOW, "warning: "),  # Severity
                 (error.BOLD, "Not good thing\n"),  # Message
                 (error.WHITE, "abcdefghijklm\n"),  # Source snippet
@@ -262,12 +264,12 @@
 
     def test_note(self):
         note_message = error.note(
-            "foo.emb", parser_types.make_location((3, 4), (3, 6)), "OK thing"
+            "foo.emb", parser_types.SourceLocation((3, 4), (3, 6)), "OK thing"
         )
         self.assertEqual("foo.emb", note_message.source_file)
         self.assertEqual(error.NOTE, note_message.severity)
         self.assertEqual(
-            parser_types.make_location((3, 4), (3, 6)), note_message.location
+            parser_types.SourceLocation((3, 4), (3, 6)), note_message.location
         )
         self.assertEqual("OK thing", note_message.message)
         sourced_format = note_message.format({"foo.emb": "\n\nabcdefghijklm"})
@@ -277,7 +279,7 @@
         )
         self.assertEqual(
             [
-                (error.BOLD, "foo.emb:3:4: "),  # Location
+                (error.BOLD, "foo.emb:3:4: "),  # SourceLocation
                 (error.WHITE, "note: "),  # Severity
                 (error.WHITE, "OK thing\n"),  # Message
                 (error.WHITE, "abcdefghijklm\n"),  # Source snippet
@@ -288,27 +290,31 @@
 
     def test_equality(self):
         note_message = error.note(
-            "foo.emb", parser_types.make_location((3, 4), (3, 6)), "thing"
+            "foo.emb", parser_types.SourceLocation((3, 4), (3, 6)), "thing"
         )
         self.assertEqual(
             note_message,
-            error.note("foo.emb", parser_types.make_location((3, 4), (3, 6)), "thing"),
+            error.note("foo.emb", parser_types.SourceLocation((3, 4), (3, 6)), "thing"),
         )
         self.assertNotEqual(
             note_message,
-            error.warn("foo.emb", parser_types.make_location((3, 4), (3, 6)), "thing"),
+            error.warn("foo.emb", parser_types.SourceLocation((3, 4), (3, 6)), "thing"),
         )
         self.assertNotEqual(
             note_message,
-            error.note("foo2.emb", parser_types.make_location((3, 4), (3, 6)), "thing"),
+            error.note(
+                "foo2.emb", parser_types.SourceLocation((3, 4), (3, 6)), "thing"
+            ),
         )
         self.assertNotEqual(
             note_message,
-            error.note("foo.emb", parser_types.make_location((2, 4), (3, 6)), "thing"),
+            error.note("foo.emb", parser_types.SourceLocation((2, 4), (3, 6)), "thing"),
         )
         self.assertNotEqual(
             note_message,
-            error.note("foo.emb", parser_types.make_location((3, 4), (3, 6)), "thing2"),
+            error.note(
+                "foo.emb", parser_types.SourceLocation((3, 4), (3, 6)), "thing2"
+            ),
         )
 
 
@@ -348,43 +354,43 @@
     def test_split_errors(self):
         user_error = [
             error.error(
-                "foo.emb", parser_types.make_location((1, 2), (3, 4)), "Bad thing"
+                "foo.emb", parser_types.SourceLocation((1, 2), (3, 4)), "Bad thing"
             ),
             error.note(
                 "foo.emb",
-                parser_types.make_location((3, 4), (5, 6)),
+                parser_types.SourceLocation((3, 4), (5, 6)),
                 "Note: bad thing referrent",
             ),
         ]
         user_error_2 = [
             error.error(
-                "foo.emb", parser_types.make_location((8, 9), (10, 11)), "Bad thing"
+                "foo.emb", parser_types.SourceLocation((8, 9), (10, 11)), "Bad thing"
             ),
             error.note(
                 "foo.emb",
-                parser_types.make_location((10, 11), (12, 13)),
+                parser_types.SourceLocation((10, 11), (12, 13)),
                 "Note: bad thing referrent",
             ),
         ]
         synthetic_error = [
             error.error(
-                "foo.emb", parser_types.make_location((1, 2), (3, 4)), "Bad thing"
+                "foo.emb", parser_types.SourceLocation((1, 2), (3, 4)), "Bad thing"
             ),
             error.note(
                 "foo.emb",
-                parser_types.make_location((3, 4), (5, 6), True),
+                parser_types.SourceLocation((3, 4), (5, 6), is_synthetic=True),
                 "Note: bad thing referrent",
             ),
         ]
         synthetic_error_2 = [
             error.error(
                 "foo.emb",
-                parser_types.make_location((8, 9), (10, 11), True),
+                parser_types.SourceLocation((8, 9), (10, 11), is_synthetic=True),
                 "Bad thing",
             ),
             error.note(
                 "foo.emb",
-                parser_types.make_location((10, 11), (12, 13)),
+                parser_types.SourceLocation((10, 11), (12, 13)),
                 "Note: bad thing referrent",
             ),
         ]
@@ -407,33 +413,33 @@
     def test_filter_errors(self):
         user_error = [
             error.error(
-                "foo.emb", parser_types.make_location((1, 2), (3, 4)), "Bad thing"
+                "foo.emb", parser_types.SourceLocation((1, 2), (3, 4)), "Bad thing"
             ),
             error.note(
                 "foo.emb",
-                parser_types.make_location((3, 4), (5, 6)),
+                parser_types.SourceLocation((3, 4), (5, 6)),
                 "Note: bad thing referrent",
             ),
         ]
         synthetic_error = [
             error.error(
-                "foo.emb", parser_types.make_location((1, 2), (3, 4)), "Bad thing"
+                "foo.emb", parser_types.SourceLocation((1, 2), (3, 4)), "Bad thing"
             ),
             error.note(
                 "foo.emb",
-                parser_types.make_location((3, 4), (5, 6), True),
+                parser_types.SourceLocation((3, 4), (5, 6), is_synthetic=True),
                 "Note: bad thing referrent",
             ),
         ]
         synthetic_error_2 = [
             error.error(
                 "foo.emb",
-                parser_types.make_location((8, 9), (10, 11), True),
+                parser_types.SourceLocation((8, 9), (10, 11), is_synthetic=True),
                 "Bad thing",
             ),
             error.note(
                 "foo.emb",
-                parser_types.make_location((10, 11), (12, 13)),
+                parser_types.SourceLocation((10, 11), (12, 13)),
                 "Note: bad thing referrent",
             ),
         ]
@@ -447,7 +453,7 @@
 
     def test_format_errors(self):
         errors = [
-            [error.note("foo.emb", parser_types.make_location((3, 4), (3, 6)), "note")]
+            [error.note("foo.emb", parser_types.SourceLocation((3, 4), (3, 6)), "note")]
         ]
         sources = {"foo.emb": "x\ny\nz  bcd\nq\n"}
         self.assertEqual(
diff --git a/compiler/util/ir_data.py b/compiler/util/ir_data.py
index cd12b96..7c9bf21 100644
--- a/compiler/util/ir_data.py
+++ b/compiler/util/ir_data.py
@@ -17,12 +17,14 @@
 This is limited to purely data and type annotations.
 """
 
+import collections
 import dataclasses
 import enum
 import sys
 from typing import ClassVar, Optional
 
 from compiler.util import ir_data_fields
+from compiler.util import parser_types
 
 
 @dataclasses.dataclass
@@ -101,8 +103,7 @@
                     )
             object.__setattr__(self, name, value)
 
-    # Non-PEP8 name to mimic the Google Protobuf interface.
-    def HasField(self, name):  # pylint:disable=invalid-name
+    def has_field(self, name):
         """Indicates if this class has the given field defined and it is set."""
         return getattr(self, name, None) is not None
 
@@ -112,37 +113,6 @@
 
 
 @dataclasses.dataclass
-class Position(Message):
-    """A zero-width position within a source file."""
-
-    line: int = 0
-    """Line (starts from 1)."""
-    column: int = 0
-    """Column (starts from 1)."""
-
-
-@dataclasses.dataclass
-class Location(Message):
-    """A half-open start:end range within a source file."""
-
-    start: Optional[Position] = None
-    """Beginning of the range"""
-    end: Optional[Position] = None
-    """One column past the end of the range."""
-
-    is_disjoint_from_parent: Optional[bool] = None
-    """True if this Location is outside of the parent object's Location."""
-
-    is_synthetic: Optional[bool] = None
-    """True if this Location's parent was synthesized, and does not directly
-  appear in the source file.
-
-  The Emboss front end uses this field to cull
-  irrelevant error messages.
-  """
-
-
-@dataclasses.dataclass
 class Word(Message):
     """IR for a bare word in the source file.
 
@@ -150,7 +120,7 @@
     """
 
     text: Optional[str] = None
-    source_location: Optional[Location] = None
+    source_location: Optional[parser_types.SourceLocation] = None
 
 
 @dataclasses.dataclass
@@ -158,13 +128,13 @@
     """IR for a string in the source file."""
 
     text: Optional[str] = None
-    source_location: Optional[Location] = None
+    source_location: Optional[parser_types.SourceLocation] = None
 
 
 @dataclasses.dataclass
 class Documentation(Message):
     text: Optional[str] = None
-    source_location: Optional[Location] = None
+    source_location: Optional[parser_types.SourceLocation] = None
 
 
 @dataclasses.dataclass
@@ -172,14 +142,14 @@
     """IR for a boolean constant."""
 
     value: Optional[bool] = None
-    source_location: Optional[Location] = None
+    source_location: Optional[parser_types.SourceLocation] = None
 
 
 @dataclasses.dataclass
 class Empty(Message):
     """Placeholder message for automatic element counts for arrays."""
 
-    source_location: Optional[Location] = None
+    source_location: Optional[parser_types.SourceLocation] = None
 
 
 @dataclasses.dataclass
@@ -192,7 +162,7 @@
     # TODO(bolms): switch back to int, and just use strings during
     # serialization, now that we're free of proto.
     value: Optional[str] = None
-    source_location: Optional[Location] = None
+    source_location: Optional[parser_types.SourceLocation] = None
 
 
 class FunctionMapping(int, enum.Enum):
@@ -240,7 +210,7 @@
     function: Optional[FunctionMapping] = None
     args: list["Expression"] = ir_data_fields.list_field(lambda: Expression)
     function_name: Optional[Word] = None
-    source_location: Optional[Location] = None
+    source_location: Optional[parser_types.SourceLocation] = None
 
 
 @dataclasses.dataclass
@@ -310,7 +280,7 @@
   should not be visible outside of its immediate namespace.
   """
 
-    source_location: Optional[Location] = None
+    source_location: Optional[parser_types.SourceLocation] = None
     """The location of this NameDefinition in source code."""
 
 
@@ -356,7 +326,7 @@
 
     # TODO(bolms): Allow absolute paths starting with ".".
 
-    source_location: Optional[Location] = None
+    source_location: Optional[parser_types.SourceLocation] = None
     """Note that this is the source_location of the *Reference*, not of the
   object to which it refers.
   """
@@ -406,7 +376,7 @@
     # TODO(bolms): Make the above change before declaring the IR to be "stable".
 
     path: list[Reference] = ir_data_fields.list_field(Reference)
-    source_location: Optional[Location] = None
+    source_location: Optional[parser_types.SourceLocation] = None
 
 
 @dataclasses.dataclass
@@ -509,7 +479,7 @@
     builtin_reference: Optional[Reference] = ir_data_fields.oneof_field("expression")
 
     type: Optional[ExpressionType] = None
-    source_location: Optional[Location] = None
+    source_location: Optional[parser_types.SourceLocation] = None
 
 
 @dataclasses.dataclass
@@ -521,7 +491,7 @@
     element_count: Optional[Expression] = ir_data_fields.oneof_field("size")
     automatic: Optional[Empty] = ir_data_fields.oneof_field("size")
 
-    source_location: Optional[Location] = None
+    source_location: Optional[parser_types.SourceLocation] = None
 
 
 @dataclasses.dataclass
@@ -530,7 +500,7 @@
 
     reference: Optional[Reference] = None
     runtime_parameter: list[Expression] = ir_data_fields.list_field(Expression)
-    source_location: Optional[Location] = None
+    source_location: Optional[parser_types.SourceLocation] = None
 
 
 @dataclasses.dataclass
@@ -541,7 +511,7 @@
     array_type: Optional[ArrayType] = ir_data_fields.oneof_field("type")
 
     size_in_bits: Optional[Expression] = None
-    source_location: Optional[Location] = None
+    source_location: Optional[parser_types.SourceLocation] = None
 
 
 @dataclasses.dataclass
@@ -553,7 +523,7 @@
     expression: Optional[Expression] = ir_data_fields.oneof_field("value")
     string_constant: Optional[String] = ir_data_fields.oneof_field("value")
 
-    source_location: Optional[Location] = None
+    source_location: Optional[parser_types.SourceLocation] = None
 
 
 @dataclasses.dataclass
@@ -564,7 +534,7 @@
     value: Optional[AttributeValue] = None
     back_end: Optional[Word] = None
     is_default: Optional[bool] = None
-    source_location: Optional[Location] = None
+    source_location: Optional[parser_types.SourceLocation] = None
 
 
 @dataclasses.dataclass
@@ -618,7 +588,7 @@
 
     start: Optional[Expression] = None
     size: Optional[Expression] = None
-    source_location: Optional[Location] = None
+    source_location: Optional[parser_types.SourceLocation] = None
 
 
 @dataclasses.dataclass
@@ -689,7 +659,7 @@
   `bar`: those fields only conditionally exist in the structure.
   """
 
-    source_location: Optional[Location] = None
+    source_location: Optional[parser_types.SourceLocation] = None
 
 
 @dataclasses.dataclass
@@ -733,7 +703,7 @@
   be `{ 0, 1, 2, 3, ... }`.
   """
 
-    source_location: Optional[Location] = None
+    source_location: Optional[parser_types.SourceLocation] = None
 
 
 @dataclasses.dataclass
@@ -743,7 +713,7 @@
     # Externals have no values other than name and attribute list, which are
     # common to all type definitions.
 
-    source_location: Optional[Location] = None
+    source_location: Optional[parser_types.SourceLocation] = None
 
 
 @dataclasses.dataclass
@@ -759,7 +729,7 @@
     attribute: list[Attribute] = ir_data_fields.list_field(Attribute)
     """Value-specific attributes."""
 
-    source_location: Optional[Location] = None
+    source_location: Optional[parser_types.SourceLocation] = None
 
 
 @dataclasses.dataclass
@@ -767,7 +737,7 @@
     """IR for an enumerated type definition."""
 
     value: list[EnumValue] = ir_data_fields.list_field(EnumValue)
-    source_location: Optional[Location] = None
+    source_location: Optional[parser_types.SourceLocation] = None
 
 
 @dataclasses.dataclass
@@ -778,7 +748,7 @@
     """The file to import."""
     local_name: Optional[Word] = None
     """The name to use within this module."""
-    source_location: Optional[Location] = None
+    source_location: Optional[parser_types.SourceLocation] = None
 
 
 @dataclasses.dataclass
@@ -808,7 +778,7 @@
   is filled in after initial parsing is finished.
   """
 
-    source_location: Optional[Location] = None
+    source_location: Optional[parser_types.SourceLocation] = None
 
 
 class AddressableUnit(int, enum.Enum):
@@ -852,7 +822,7 @@
   These are currently only allowed on structures, but in the future they
   should be allowed on externals.
   """
-    source_location: Optional[Location] = None
+    source_location: Optional[parser_types.SourceLocation] = None
 
 
 @dataclasses.dataclass
@@ -869,7 +839,7 @@
     """Other modules imported."""
     source_text: Optional[str] = None
     """The original source code."""
-    source_location: Optional[Location] = None
+    source_location: Optional[parser_types.SourceLocation] = None
     """Source code covered by this IR."""
     source_file_name: Optional[str] = None
     """Name of the source file."""
diff --git a/compiler/util/ir_data_fields_test.py b/compiler/util/ir_data_fields_test.py
index 0376b69..36264b8 100644
--- a/compiler/util/ir_data_fields_test.py
+++ b/compiler/util/ir_data_fields_test.py
@@ -22,6 +22,7 @@
 
 from compiler.util import ir_data
 from compiler.util import ir_data_fields
+from compiler.util import parser_types
 
 
 class TestEnum(enum.Enum):
diff --git a/compiler/util/ir_data_utils.py b/compiler/util/ir_data_utils.py
index e7679a6..529c9a4 100644
--- a/compiler/util/ir_data_utils.py
+++ b/compiler/util/ir_data_utils.py
@@ -29,14 +29,14 @@
   if not function.function_name:
     function.function_name = Word()
   if not function.function_name.source_location:
-    function.function_name.source_location = Location()
-  word.source_location.end = Position(line=1,column=2)
+    function.function_name.source_location = SourceLocation()
+  word.source_location.end = SourcePosition(line=1,column=2)
 ```
 
 We can do:
 ```
 def set_function_name_end(function: Function):
-  builder(function).function_name.source_location.end = Position(line=1,
+  builder(function).function_name.source_location.end = SourcePosition(line=1,
   column=2)
 ```
 
@@ -79,6 +79,7 @@
 
 from compiler.util import ir_data
 from compiler.util import ir_data_fields
+from compiler.util import parser_types
 
 
 MessageT = TypeVar("MessageT", bound=ir_data.Message)
@@ -106,11 +107,14 @@
         assert ir is not None
         values: MutableMapping[str, Any] = {}
         for spec, value in field_func(ir):
-            if value is not None and spec.is_dataclass:
-                if spec.is_sequence:
-                    value = [self._to_dict(v, field_func) for v in value]
-                else:
-                    value = self._to_dict(value, field_func)
+            if value is not None:
+                if spec.is_dataclass:
+                    if spec.is_sequence:
+                        value = [self._to_dict(v, field_func) for v in value]
+                    else:
+                        value = self._to_dict(value, field_func)
+                elif spec.data_type == parser_types.SourceLocation:
+                    value = str(value)
             values[spec.name] = value
         return values
 
@@ -182,6 +186,8 @@
                         class_fields[name] = IrDataSerializer._enum_type_converter(
                             spec.data_type, value
                         )
+                    elif spec.data_type == parser_types.SourceLocation:
+                        class_fields[name] = parser_types.SourceLocation.from_str(value)
                     else:
                         if spec.is_sequence:
                             class_fields[name] = value
@@ -277,7 +283,7 @@
         if ir is None:
             return object.__getattribute__(self, name)
 
-        if name in ("HasField",):
+        if name in ("has_field",):
             return getattr(ir, name)
 
         field_spec = field_specs(ir).get(name)
@@ -360,7 +366,7 @@
         spec = field_specs(field_type).get(name)
         if not spec:
             if isinstance(ir_or_spec, ir_data_fields.FieldSpec):
-                if name == "HasField":
+                if name == "has_field":
                     return lambda x: False
                 # This *should* be limited to only the `which_` attributes that
                 # correspond to real oneofs, but that would add complexity and
diff --git a/compiler/util/ir_data_utils_test.py b/compiler/util/ir_data_utils_test.py
index 19ae579..8475e01 100644
--- a/compiler/util/ir_data_utils_test.py
+++ b/compiler/util/ir_data_utils_test.py
@@ -23,6 +23,7 @@
 from compiler.util import ir_data
 from compiler.util import ir_data_fields
 from compiler.util import ir_data_utils
+from compiler.util import parser_types
 
 
 class TestEnum(enum.Enum):
@@ -103,7 +104,7 @@
         # Try a IR data class
         expected_field = ir_data_fields.make_field_spec(
             "source_location",
-            ir_data.Location,
+            parser_types.SourceLocation,
             ir_data_fields.FieldContainer.OPTIONAL,
             None,
         )
@@ -119,11 +120,11 @@
         self.assertEqual(fields["external"], expected_field)
 
         # Try non-optional scalar
-        fields = ir_data_utils.field_specs(ir_data.Position)
+        fields = ir_data_utils.field_specs(ir_data.CanonicalName)
         expected_field = ir_data_fields.make_field_spec(
-            "line", int, ir_data_fields.FieldContainer.NONE, None
+            "module_file", str, ir_data_fields.FieldContainer.NONE, None
         )
-        self.assertEqual(fields["line"], expected_field)
+        self.assertEqual(fields["module_file"], expected_field)
 
         fields = ir_data_utils.field_specs(ir_data.ArrayType)
         expected_field = ir_data_fields.make_field_spec(
@@ -254,7 +255,7 @@
         """Tests that basic builder chains work."""
         # We start with an empty type
         type_def = ir_data.TypeDefinition()
-        self.assertFalse(type_def.HasField("name"))
+        self.assertFalse(type_def.has_field("name"))
         self.assertIsNone(type_def.name)
 
         # Now setup a builder
@@ -281,7 +282,7 @@
         """Tests that sequences are properly wrapped."""
         # We start with an empty type
         type_def = ir_data.TypeDefinition()
-        self.assertTrue(type_def.HasField("attribute"))
+        self.assertTrue(type_def.has_field("attribute"))
         self.assertEmpty(type_def.attribute)
 
         # Now setup a builder
@@ -295,7 +296,7 @@
 
         builder.attribute.append(attribute)
         self.assertEqual(builder.attribute, [attribute])
-        self.assertTrue(type_def.HasField("attribute"))
+        self.assertTrue(type_def.has_field("attribute"))
         self.assertLen(type_def.attribute, 1)
         self.assertEqual(type_def.attribute[0], attribute)
 
@@ -330,9 +331,9 @@
 
     def test_copy_from(self) -> None:
         """Tests that `CopyFrom` works."""
-        location = ir_data.Location(
-            start=ir_data.Position(line=1, column=1),
-            end=ir_data.Position(line=1, column=2),
+        location = parser_types.SourceLocation(
+            start=parser_types.SourcePosition(line=1, column=1),
+            end=parser_types.SourcePosition(line=1, column=2),
         )
         expression_ir = ir_data.Expression(source_location=location)
         template: ir_data.Expression = expression_parser.parse("x + y")
@@ -355,9 +356,9 @@
         self.assertIsInstance(template.function, ir_data.Function)
         self.assertIsInstance(template.function.args, ir_data_fields.CopyValuesList)
 
-        location = ir_data.Location(
-            start=ir_data.Position(line=1, column=1),
-            end=ir_data.Position(line=1, column=2),
+        location = parser_types.SourceLocation(
+            start=parser_types.SourcePosition(line=1, column=1),
+            end=parser_types.SourcePosition(line=1, column=2),
         )
         expression_ir = ir_data.Expression(source_location=location)
         self.assertIsInstance(expression_ir, ir_data.Expression)
@@ -391,7 +392,7 @@
         builder.fields_in_dependency_order.append(12)
         builder.fields_in_dependency_order.append(11)
 
-        self.assertTrue(structure.HasField("fields_in_dependency_order"))
+        self.assertTrue(structure.has_field("fields_in_dependency_order"))
         self.assertLen(structure.fields_in_dependency_order, 2)
         self.assertEqual(structure.fields_in_dependency_order[0], 12)
         self.assertEqual(structure.fields_in_dependency_order[1], 11)
@@ -405,7 +406,7 @@
             expression=ir_data.Expression(boolean_constant=ir_data.BooleanConstant())
         )
         builder = ir_data_utils.builder(value)
-        self.assertTrue(builder.HasField("expression"))
+        self.assertTrue(builder.has_field("expression"))
         self.assertFalse(builder.expression.boolean_constant.value)
         builder.expression.boolean_constant.value = True
         self.assertTrue(builder.expression.boolean_constant.value)
@@ -515,11 +516,7 @@
             {
                 "constant": {
                     "value": "0",
-                    "source_location": {
-                        "start": {"line": 421, "column": 3},
-                        "end": {"line": 421, "column": 4},
-                        "is_synthetic": False,
-                    },
+                    "source_location": "421:3-421:4",
                 },
                 "type": {
                     "integer": {
@@ -529,20 +526,12 @@
                         "maximum_value": "0",
                     }
                 },
-                "source_location": {
-                    "start": {"line": 421, "column": 3},
-                    "end": {"line": 421, "column": 4},
-                    "is_synthetic": False,
-                },
+                "source_location": "421:3-421:4",
             },
             {
                 "constant": {
                     "value": "1",
-                    "source_location": {
-                        "start": {"line": 421, "column": 11},
-                        "end": {"line": 421, "column": 12},
-                        "is_synthetic": False,
-                    },
+                    "source_location": "421:11-421:12",
                 },
                 "type": {
                     "integer": {
@@ -552,11 +541,7 @@
                         "maximum_value": "1",
                     }
                 },
-                "source_location": {
-                    "start": {"line": 421, "column": 11},
-                    "end": {"line": 421, "column": 12},
-                    "is_synthetic": False,
-                },
+                "source_location": "421:11-421:12",
             },
         ]
         function_data = {"args": function_args}
@@ -595,12 +580,12 @@
         # Scalar field should pass through
         self.assertEqual(field_checker.non_union_field, 10)
 
-        # Make sure HasField works
-        self.assertTrue(field_checker.HasField("opaque"))
-        self.assertFalse(field_checker.HasField("integer"))
-        self.assertTrue(field_checker.HasField("boolean"))
-        self.assertFalse(field_checker.HasField("enumeration"))
-        self.assertTrue(field_checker.HasField("non_union_field"))
+        # Make sure has_field works
+        self.assertTrue(field_checker.has_field("opaque"))
+        self.assertFalse(field_checker.has_field("integer"))
+        self.assertTrue(field_checker.has_field("boolean"))
+        self.assertFalse(field_checker.has_field("enumeration"))
+        self.assertTrue(field_checker.has_field("non_union_field"))
 
     def test_construct_from_field_checker(self):
         """Tests that constructing from another field checker works."""
@@ -619,12 +604,12 @@
         # Scalar field should pass through
         self.assertEqual(field_checker.non_union_field, 10)
 
-        # Make sure HasField works
-        self.assertTrue(field_checker.HasField("opaque"))
-        self.assertFalse(field_checker.HasField("integer"))
-        self.assertTrue(field_checker.HasField("boolean"))
-        self.assertFalse(field_checker.HasField("enumeration"))
-        self.assertTrue(field_checker.HasField("non_union_field"))
+        # Make sure has_field works
+        self.assertTrue(field_checker.has_field("opaque"))
+        self.assertFalse(field_checker.has_field("integer"))
+        self.assertTrue(field_checker.has_field("boolean"))
+        self.assertFalse(field_checker.has_field("enumeration"))
+        self.assertTrue(field_checker.has_field("non_union_field"))
 
     def test_read_only(self) -> None:
         """Tests that the read only wrapper really is read only."""
diff --git a/compiler/util/ir_util.py b/compiler/util/ir_util.py
index c1de244..e8e8b8f 100644
--- a/compiler/util/ir_util.py
+++ b/compiler/util/ir_util.py
@@ -49,7 +49,7 @@
         requested attribute is not found or has a non-boolean value.
     """
     attribute_value = get_attribute(attribute_list, name)
-    if not attribute_value or not attribute_value.expression.HasField(
+    if not attribute_value or not attribute_value.expression.has_field(
         "boolean_constant"
     ):
         return default_value
@@ -88,8 +88,8 @@
     expression_type = ir_data_utils.reader(expression_type)
     return (
         expression_type.integer.modulus == "infinity"
-        or expression_type.boolean.HasField("value")
-        or expression_type.enumeration.HasField("value")
+        or expression_type.boolean.has_field("value")
+        or expression_type.enumeration.has_field("value")
     )
 
 
@@ -108,10 +108,10 @@
             assert expression.type.integer.modulus == "infinity"
             return int(expression.type.integer.modular_value)
         elif expression.type.which_type == "boolean":
-            assert expression.type.boolean.HasField("value")
+            assert expression.type.boolean.has_field("value")
             return expression.type.boolean.value
         elif expression.type.which_type == "enumeration":
-            assert expression.type.enumeration.HasField("value")
+            assert expression.type.enumeration.has_field("value")
             return int(expression.type.enumeration.value)
         else:
             assert False, "Unexpected expression type {}".format(
@@ -239,7 +239,7 @@
 
 def is_array(type_ir):
     """Returns true if type_ir is an array type."""
-    return type_ir.HasField("array_type")
+    return type_ir.has_field("array_type")
 
 
 def _find_path_in_structure_field(path, field):
@@ -265,7 +265,7 @@
 
 
 def _find_path_in_parameters(path, type_definition):
-    if len(path) > 1 or not type_definition.HasField("runtime_parameter"):
+    if len(path) > 1 or not type_definition.has_field("runtime_parameter"):
         return None
     for parameter in type_definition.runtime_parameter:
         if ir_data_utils.reader(parameter).name.name.text == path[0]:
@@ -280,9 +280,9 @@
     obj = _find_path_in_parameters(path, type_definition)
     if obj:
         return obj
-    if type_definition.HasField("structure"):
+    if type_definition.has_field("structure"):
         obj = _find_path_in_structure(path, type_definition)
-    elif type_definition.HasField("enumeration"):
+    elif type_definition.has_field("enumeration"):
         obj = _find_path_in_enumeration(path, type_definition)
     if obj:
         return obj
@@ -348,9 +348,9 @@
       type_ir corresponds to an array type (like "UInt:8[12]" or "Square[8][8]"),
       returns the type after stripping off the array types ("UInt" or "Square").
     """
-    while type_ir.HasField("array_type"):
+    while type_ir.has_field("array_type"):
         type_ir = type_ir.array_type.base_type
-    assert type_ir.HasField("atomic_type"), "Unknown kind of type {}".format(type_ir)
+    assert type_ir.has_field("atomic_type"), "Unknown kind of type {}".format(type_ir)
     return type_ir
 
 
@@ -365,7 +365,7 @@
       size if the size of the type can be determined, otherwise None.
     """
     array_multiplier = 1
-    while type_ir.HasField("array_type"):
+    while type_ir.has_field("array_type"):
         if type_ir.array_type.which_size == "automatic":
             return None
         else:
@@ -377,12 +377,12 @@
             return None
         else:
             array_multiplier *= constant_value(element_count)
-        assert not type_ir.HasField(
+        assert not type_ir.has_field(
             "size_in_bits"
         ), "TODO(bolms): implement explicitly-sized arrays"
         type_ir = type_ir.array_type.base_type
-    assert type_ir.HasField("atomic_type"), "Unexpected type!"
-    if type_ir.HasField("size_in_bits"):
+    assert type_ir.has_field("atomic_type"), "Unexpected type!"
+    if type_ir.has_field("size_in_bits"):
         size = constant_value(type_ir.size_in_bits)
     else:
         type_definition = find_object(type_ir.atomic_type.reference, ir)
@@ -397,7 +397,7 @@
     """Returns true if the field is virtual."""
     # TODO(bolms): Should there be a more explicit indicator that a field is
     # virtual?
-    return not field_ir.HasField("location")
+    return not field_ir.has_field("location")
 
 
 def field_is_read_only(field_ir):
diff --git a/compiler/util/ir_util_test.py b/compiler/util/ir_util_test.py
index 07cf4dc..b3deeb2 100644
--- a/compiler/util/ir_util_test.py
+++ b/compiler/util/ir_util_test.py
@@ -782,13 +782,13 @@
                 "base_type": {
                   "atomic_type": {
                     "reference": { },
-                    "source_location": { "start": { "line": 5 } }
+                    "source_location": "5:1-6:1"
                   }
                 },
-                "source_location": { "start": { "line": 4 } }
+                "source_location": "4:1-6:1"
               }
             },
-            "source_location": { "start": { "line": 3 } }
+            "source_location": "3:1-6:1"
           }
         }""",
         )
diff --git a/compiler/util/parser_types.py b/compiler/util/parser_types.py
index fffe086..a3ef34d 100644
--- a/compiler/util/parser_types.py
+++ b/compiler/util/parser_types.py
@@ -12,72 +12,172 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Various types shared through multiple passes of parsing.
+"""Types related to the LR(1) parser.
 
-This module contains types used as interfaces between parts of the Emboss front
-end.  These types do not really "belong" to either the producers or consumers,
-and in a few cases placing them in one or the other creates unnecessary
-dependencies, so they are defined here.
+This module contains types used by the LR(1) parser, which are also used in
+other parts of the compiler: 
+
+    SourcePosition: a position (zero-width) within a source file.
+    SourceLocation: a span within a source file.
+    Production: a grammar production.
+    Token: a token; lr1.Parser operates on lists of tokens.
 """
 
 import collections
-from compiler.util import ir_data
+
+PositionTuple = collections.namedtuple(
+    "PositionTuple", ["line", "column"], defaults=[0, 0]
+)
 
 
-def _make_position(line, column):
-    """Makes an ir_data.Position from line, column ints."""
-    if not isinstance(line, int):
-        raise ValueError("Bad line {!r}".format(line))
-    elif not isinstance(column, int):
-        raise ValueError("Bad column {!r}".format(column))
-    return ir_data.Position(line=line, column=column)
+class SourcePosition(PositionTuple):
+    """A zero-width position within a source file.
+
+    Positions are 1-based (the first character of a source file is (1, 1)).
+
+    The special value (0, 0) indicates a missing or unknown position, and is
+    considered falsy.  All other values of SourcePosition are truthy.
+
+    Attributes:
+        line: the line within the source file; the first line is 1
+        column: the column within the source line; the first character is 1
+    """
+
+    # This __new__ just adds asserts around PositionTuple.__new__, so it is
+    # unnecessary when running under -O.
+    if __debug__:
+
+        def __new__(cls, /, line=0, column=0):
+            assert isinstance(line, int), f"line {line} is not int"
+            assert isinstance(column, int), f"column {column} is not int"
+            assert line >= 0, f"line {line} is negative"
+            assert column >= 0, f"column {column} is negative"
+            assert (line == 0 and column == 0) or (
+                line != 0 and column != 0
+            ), f"Cannot have line {line} with column {column}"
+            return PositionTuple.__new__(cls, line, column)
+
+    def __str__(self):
+        return f"{self.line}:{self.column}"
+
+    @staticmethod
+    def from_str(value):
+        try:
+            l, c = value.split(":")
+            return SourcePosition(line=int(l.strip()), column=int(c.strip()))
+        except Exception as e:
+            raise ValueError(f"{repr(value)} is not a valid SourcePosition.")
+
+    def __bool__(self):
+        return bool(self.line)
 
 
-def _parse_position(text):
-    """Parses an ir_data.Position from "line:column" (e.g., "1:2")."""
-    line, column = text.split(":")
-    return _make_position(int(line), int(column))
+LocationTuple = collections.namedtuple(
+    "LocationTuple",
+    ["start", "end", "is_disjoint_from_parent", "is_synthetic"],
+    defaults=[SourcePosition(), SourcePosition(), False, False],
+)
 
 
-def format_position(position):
-    """formats an ir_data.Position to "line:column" form."""
-    return "{}:{}".format(position.line, position.column)
+class SourceLocation(LocationTuple):
+    """The source location of a node in the IR, as a half-open start:end range
 
+    Attributes:
+        start: the start of the range
+        end: one character past the end of the range
+        is_disjoint_from_parent: True if this SourceLocation may fall outside
+            of the SourceLocation of the parent node
+        is_synthetic: True if the associated node was generated from
+            user-supplied source code, but is part of a construct that does not
+            directly correspond to something that the user wrote (e.g., a
+            generated virtual field that is assembled from fragments from
+            elsewhere in the IR).
 
-def make_location(start, end, is_synthetic=False):
-    """Makes an ir_data.Location from (line, column) tuples or ir_data.Positions."""
-    if isinstance(start, tuple):
-        start = _make_position(*start)
-    if isinstance(end, tuple):
-        end = _make_position(*end)
-    if not isinstance(start, ir_data.Position):
-        raise ValueError("Bad start {!r}".format(start))
-    elif not isinstance(end, ir_data.Position):
-        raise ValueError("Bad end {!r}".format(end))
-    elif start.line > end.line or (
-        start.line == end.line and start.column > end.column
+    SourceLocation is falsy if the start and end are falsy.
+    """
+
+    def __new__(
+        cls,
+        /,
+        start=SourcePosition(),
+        end=SourcePosition(),
+        *,
+        is_disjoint_from_parent=False,
+        is_synthetic=False,
     ):
-        raise ValueError(
-            "Start {} is after end {}".format(
-                format_position(start), format_position(end)
-            )
+        if not isinstance(start, SourcePosition):
+            start = SourcePosition(*start)
+        if not isinstance(end, SourcePosition):
+            end = SourcePosition(*end)
+        assert start <= end, f"start {start} is after end {end}"
+        assert (not start and not end) or (
+            start and end
+        ), "Cannot have have start {start} with end {end}"
+        assert isinstance(
+            is_disjoint_from_parent, bool
+        ), f"is_disjoint_from_parent {is_disjoint_from_parent} is not bool"
+        assert isinstance(
+            is_synthetic, bool
+        ), f"is_synthetic {is_synthetic} is not bool"
+        return LocationTuple.__new__(
+            cls, start, end, is_disjoint_from_parent, is_synthetic
         )
-    return ir_data.Location(start=start, end=end, is_synthetic=is_synthetic)
+
+    def __str__(self):
+        suffix = ""
+        if self.is_disjoint_from_parent:
+            suffix += "^"
+        if self.is_synthetic:
+            suffix += "*"
+        return f"{self.start}-{self.end}{suffix}"
+
+    @staticmethod
+    def from_str(value):
+        original_value = value
+        try:
+            is_synthetic = False
+            if value[-1] == "*":
+                is_synthetic = True
+                value = value[:-1]
+            is_disjoint_from_parent = False
+            if value[-1] == "^":
+                is_disjoint_from_parent = True
+                value = value[:-1]
+            start, end = value.split("-")
+            return SourceLocation(
+                start=SourcePosition.from_str(start),
+                end=SourcePosition.from_str(end),
+                is_synthetic=is_synthetic,
+                is_disjoint_from_parent=is_disjoint_from_parent,
+            )
+        except Exception as e:
+            raise ValueError(f"{repr(original_value)} is not a valid SourceLocation.")
+
+    def __bool__(self):
+        # Should this check is_synthetic and is_disjoint_from_parent as well?
+        return bool(self.start)
 
 
-def format_location(location):
-    """Formats an ir_data.Location in format "1:2-3:4" ("start-end")."""
-    return "{}-{}".format(
-        format_position(location.start), format_position(location.end)
+def merge_source_locations(*nodes):
+    locations = [
+        node.source_location
+        for node in nodes
+        if hasattr(node, "source_location") and node.source_location
+    ]
+    if not locations:
+        return None
+    start = locations[0].start
+    end = locations[-1].end
+    is_synthetic = any(l.is_synthetic for l in locations)
+    is_disjoint_from_parent = any(l.is_disjoint_from_parent for l in locations)
+    return SourceLocation(
+        start=start,
+        end=end,
+        is_synthetic=is_synthetic,
+        is_disjoint_from_parent=is_disjoint_from_parent,
     )
 
 
-def parse_location(text):
-    """Parses an ir_data.Location from format "1:2-3:4" ("start-end")."""
-    start, end = text.split("-")
-    return make_location(_parse_position(start), _parse_position(end))
-
-
 class Token(collections.namedtuple("Token", ["symbol", "text", "source_location"])):
     """A Token is a chunk of text from a source file, and a classification.
 
@@ -89,7 +189,7 @@
 
     def __str__(self):
         return "{} {} {}".format(
-            self.symbol, repr(self.text), format_location(self.source_location)
+            self.symbol, repr(self.text), str(self.source_location)
         )
 
 
diff --git a/compiler/util/parser_types_test.py b/compiler/util/parser_types_test.py
index 097ece4..c66bf2f 100644
--- a/compiler/util/parser_types_test.py
+++ b/compiler/util/parser_types_test.py
@@ -20,82 +20,188 @@
 
 
 class PositionTest(unittest.TestCase):
-    """Tests for Position-related functions in parser_types."""
+    """Tests for SourcePosition-related functions in parser_types."""
 
-    def test_format_position(self):
+    def test_position_str(self):
+        self.assertEqual("1:2", str(parser_types.SourcePosition(line=1, column=2)))
+
+    def test_position_bool(self):
+        self.assertFalse(parser_types.SourcePosition())
+        self.assertFalse(parser_types.SourcePosition(0, 0))
+        self.assertTrue(parser_types.SourcePosition(1, 1))
+
+    def test_position_from_str(self):
         self.assertEqual(
-            "1:2", parser_types.format_position(ir_data.Position(line=1, column=2))
+            parser_types.SourcePosition(1, 2),
+            parser_types.SourcePosition.from_str("1:2"),
+        )
+        self.assertEqual(
+            parser_types.SourcePosition(0, 0),
+            parser_types.SourcePosition.from_str("0:0"),
+        )
+        self.assertRaises(ValueError, parser_types.SourcePosition.from_str, "0xa:9")
+        self.assertRaises(ValueError, parser_types.SourcePosition.from_str, "9")
+        if __debug__:
+            self.assertRaises(ValueError, parser_types.SourcePosition.from_str, "0:-1")
+            self.assertRaises(ValueError, parser_types.SourcePosition.from_str, "-1:0")
+
+    def test_position_new(self):
+        self.assertEqual(
+            parser_types.SourcePosition(1, 2),
+            parser_types.SourcePosition(line=1, column=2),
+        )
+        if __debug__:
+            self.assertRaises(AssertionError, parser_types.SourcePosition, -1, 1)
+            self.assertRaises(AssertionError, parser_types.SourcePosition, 1, -1)
+            self.assertRaises(AssertionError, parser_types.SourcePosition, None, 1)
+            self.assertRaises(AssertionError, parser_types.SourcePosition, 1, None)
+            self.assertRaises(AssertionError, parser_types.SourcePosition, 1.1, 1)
+            self.assertRaises(AssertionError, parser_types.SourcePosition, 1, 1.1)
+            self.assertRaises(AssertionError, parser_types.SourcePosition, 0, 1)
+            self.assertRaises(AssertionError, parser_types.SourcePosition, 1, 0)
+
+    def test_position_attributes(self):
+        self.assertEqual(1, parser_types.SourcePosition(1, 2).line)
+        self.assertEqual(2, parser_types.SourcePosition(1, 2).column)
+
+    def test_position_order(self):
+        self.assertTrue(
+            parser_types.SourcePosition(1, 2) < parser_types.SourcePosition(2, 2)
+        )
+        self.assertTrue(
+            parser_types.SourcePosition(2, 1) < parser_types.SourcePosition(2, 2)
+        )
+        self.assertFalse(
+            parser_types.SourcePosition(2, 1) < parser_types.SourcePosition(2, 1)
+        )
+        self.assertFalse(
+            parser_types.SourcePosition(2, 2) < parser_types.SourcePosition(2, 1)
         )
 
 
 class LocationTest(unittest.TestCase):
-    """Tests for Location-related functions in parser_types."""
+    """Tests for SourceLocation-related functions in parser_types."""
 
-    def test_make_location(self):
+    def test_location_new(self):
         self.assertEqual(
-            ir_data.Location(
-                start=ir_data.Position(line=1, column=2),
-                end=ir_data.Position(line=3, column=4),
+            parser_types.SourceLocation(
+                start=parser_types.SourcePosition(line=1, column=2),
+                end=parser_types.SourcePosition(line=3, column=4),
                 is_synthetic=False,
+                is_disjoint_from_parent=False,
             ),
-            parser_types.make_location((1, 2), (3, 4)),
+            parser_types.SourceLocation((1, 2), (3, 4)),
         )
-        self.assertEqual(
-            ir_data.Location(
-                start=ir_data.Position(line=1, column=2),
-                end=ir_data.Position(line=3, column=4),
-                is_synthetic=False,
-            ),
-            parser_types.make_location(
-                ir_data.Position(line=1, column=2), ir_data.Position(line=3, column=4)
-            ),
+        self.assertFalse(parser_types.SourceLocation(is_synthetic=False).is_synthetic)
+        self.assertTrue(parser_types.SourceLocation(is_synthetic=True).is_synthetic)
+        self.assertFalse(
+            parser_types.SourceLocation(
+                is_disjoint_from_parent=False
+            ).is_disjoint_from_parent
         )
-
-    def test_make_synthetic_location(self):
-        self.assertEqual(
-            ir_data.Location(
-                start=ir_data.Position(line=1, column=2),
-                end=ir_data.Position(line=3, column=4),
-                is_synthetic=True,
-            ),
-            parser_types.make_location((1, 2), (3, 4), True),
+        self.assertTrue(
+            parser_types.SourceLocation(
+                is_disjoint_from_parent=True
+            ).is_disjoint_from_parent
         )
-        self.assertEqual(
-            ir_data.Location(
-                start=ir_data.Position(line=1, column=2),
-                end=ir_data.Position(line=3, column=4),
-                is_synthetic=True,
-            ),
-            parser_types.make_location(
-                ir_data.Position(line=1, column=2),
-                ir_data.Position(line=3, column=4),
-                True,
-            ),
-        )
+        self.assertRaises(TypeError, parser_types.SourceLocation, None, (3, 4))
+        self.assertRaises(TypeError, parser_types.SourceLocation, (1, 2), None)
+        if __debug__:
+            self.assertRaises(
+                AssertionError, parser_types.SourceLocation, (3, 4), (1, 2)
+            )
+            self.assertRaises(
+                AssertionError, parser_types.SourceLocation, (3, 4), (3, 2)
+            )
+            self.assertRaises(
+                AssertionError,
+                parser_types.SourceLocation,
+                parser_types.SourcePosition(),
+                (1, 2),
+            )
+            self.assertRaises(
+                AssertionError,
+                parser_types.SourceLocation,
+                (1, 2),
+                parser_types.SourcePosition(),
+            )
 
-    def test_make_location_type_checks(self):
-        self.assertRaises(ValueError, parser_types.make_location, [1, 2], (1, 2))
-        self.assertRaises(ValueError, parser_types.make_location, (1, 2), [1, 2])
-
-    def test_make_location_logic_checks(self):
-        self.assertRaises(ValueError, parser_types.make_location, (3, 4), (1, 2))
-        self.assertRaises(ValueError, parser_types.make_location, (1, 3), (1, 2))
-        self.assertTrue(parser_types.make_location((1, 2), (1, 2)))
-
-    def test_format_location(self):
+    def test_location_str(self):
         self.assertEqual(
             "1:2-3:4",
-            parser_types.format_location(parser_types.make_location((1, 2), (3, 4))),
+            str(parser_types.SourceLocation((1, 2), (3, 4))),
+        )
+        self.assertEqual(
+            "1:2-3:4^",
+            str(
+                parser_types.SourceLocation(
+                    (1, 2), (3, 4), is_disjoint_from_parent=True
+                )
+            ),
+        )
+        self.assertEqual(
+            "1:2-3:4*",
+            str(parser_types.SourceLocation((1, 2), (3, 4), is_synthetic=True)),
+        )
+        self.assertEqual(
+            "1:2-3:4^*",
+            str(
+                parser_types.SourceLocation(
+                    (1, 2), (3, 4), is_synthetic=True, is_disjoint_from_parent=True
+                )
+            ),
         )
 
-    def test_parse_location(self):
+    def test_location_from_str(self):
         self.assertEqual(
-            parser_types.make_location((1, 2), (3, 4)),
-            parser_types.parse_location("1:2-3:4"),
+            parser_types.SourceLocation((1, 2), (3, 4)),
+            parser_types.SourceLocation.from_str("1:2-3:4"),
         )
         self.assertEqual(
-            parser_types.make_location((1, 2), (3, 4)),
-            parser_types.parse_location("  1  :  2  -    3 :   4  "),
+            parser_types.SourceLocation((1, 2), (3, 4)),
+            parser_types.SourceLocation.from_str("  1  :  2  -    3 :   4  "),
+        )
+        self.assertEqual(
+            parser_types.SourceLocation((1, 2), (3, 4), is_disjoint_from_parent=True),
+            parser_types.SourceLocation.from_str("1:2-3:4^"),
+        )
+        self.assertEqual(
+            parser_types.SourceLocation((1, 2), (3, 4), is_synthetic=True),
+            parser_types.SourceLocation.from_str("1:2-3:4*"),
+        )
+        self.assertEqual(
+            parser_types.SourceLocation(
+                (1, 2), (3, 4), is_disjoint_from_parent=True, is_synthetic=True
+            ),
+            parser_types.SourceLocation.from_str("1:2-3:4^*"),
+        )
+        self.assertRaises(ValueError, parser_types.SourceLocation.from_str, "1:2-3:")
+        if __debug__:
+            self.assertRaises(
+                ValueError, parser_types.SourceLocation.from_str, "1:2-3:-1"
+            )
+        self.assertRaises(ValueError, parser_types.SourceLocation.from_str, "1:2-3:1%")
+
+    def test_location_attributes(self):
+        self.assertEqual(
+            parser_types.SourceLocation((1, 2), (3, 4)).start,
+            parser_types.SourcePosition(1, 2),
+        )
+        self.assertEqual(
+            parser_types.SourceLocation((1, 2), (3, 4)).end,
+            parser_types.SourcePosition(3, 4),
+        )
+        self.assertFalse(parser_types.SourceLocation((1, 2), (3, 4)).is_synthetic)
+        self.assertFalse(
+            parser_types.SourceLocation((1, 2), (3, 4)).is_disjoint_from_parent
+        )
+        self.assertTrue(
+            parser_types.SourceLocation((1, 2), (3, 4), is_synthetic=True).is_synthetic
+        )
+        self.assertTrue(
+            parser_types.SourceLocation(
+                (1, 2), (3, 4), is_disjoint_from_parent=True
+            ).is_disjoint_from_parent
         )
 
 
@@ -107,7 +213,7 @@
             "FOO 'bar' 1:2-3:4",
             str(
                 parser_types.Token(
-                    "FOO", "bar", parser_types.make_location((1, 2), (3, 4))
+                    "FOO", "bar", parser_types.SourceLocation((1, 2), (3, 4))
                 )
             ),
         )
diff --git a/compiler/util/parser_util.py b/compiler/util/parser_util.py
new file mode 100644
index 0000000..c95f70a
--- /dev/null
+++ b/compiler/util/parser_util.py
@@ -0,0 +1,138 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Utilities for working with parse trees."""
+
+from compiler.util import parser_types
+
+
+def transform_parse_tree(
+    parse_tree, token_handler, production_handlers, used_productions=None
+):
+    """Walks the provided parse_tree, calling handlers for each node.
+
+    This function uses provided handlers to transform a parse tree into a new
+    structure.  From the bottom up, calls a handler on each node, passing the
+    node itself and the results of calling handlers on each child of the node
+    (if any).
+
+    This function avoids recursion, so it is suitable for very deep parse
+    trees.
+
+    Arguments:
+        parse_tree: the tree to process
+        token_handler: the handler to use for Token nodes.
+        production_handlers: a map from productions to handlers for those
+            productions.
+        used_productions: an optional set; all encountered productions will be
+            added to used_productions.
+
+    Returns:
+        The result of the production_handler for the top-level parse_tree node.
+    """
+    # The stack of entries to process.  Each entry is in one of two states,
+    # depending on the 3rd element (children_completed):
+    #
+    # If False, the node's children have not been added, and the action is to
+    # push the same node with children_completed=True, then push each an entry
+    # for each of node's children with their children_completed=False.
+    #
+    # If True, the node's children have been added and (by the time the entry
+    # is back on top of the stack) all of them have been processed.  In this
+    # case, the action is to call the appropriate handler (token_handler() or
+    # production_handlers[node.production]()) with the node and its transformed
+    # children, then store the result in the node's parent's
+    # transformed_children list.
+    #
+    # As an example, if we have:
+    #
+    #                                A
+    #                               / \
+    #                              B   C
+    #                                 / \
+    #                                D   E
+    #
+    # Then the steps are:
+    #
+    # Initialize:
+    # 1.  Push (A, children_completed=False)
+    #
+    # Start handling A:
+    # 2.  Pop (A, children_completed=False)
+    # 3.  Push (A, children_completed=True)
+    # 4.  Push (B, children_completed=False)
+    # 5.  Push (C, children_completed=False)
+    #
+    # Start handling C:
+    # 6.  Pop (C, children_completed=False)
+    # 7.  Push (C, children_completed=True)
+    # 8.  Push (D, children_completed=False)
+    # 9.  Push (E, children_completed=False)
+    #
+    # Start handling E:
+    # 10. Pop (E, children_completed=False)
+    # 11. Push (E, children_completed=True)
+    #
+    # Finish handling E:
+    # 12. Pop (E, children_completed=True)
+    # 13. Insert token_handler(E) into C.transformed_children
+    #
+    # Start handling D:
+    # 14. Pop (D, children_completed=False)
+    # 15. Push (D, children_completed=True)
+    #
+    # Finish handling D:
+    # 16. Pop (D, children_completed=True)
+    # 17. Insert token_handler(D) into C.transformed_children
+    #
+    # Finish handling C:
+    # 18. Pop (C, children_completed=True)
+    # 19. Insert production_handlers[C.production](C, *C.transformed_children)
+    #     into A.transformed_children
+    #
+    # Start handling B:
+    # 20. Pop (B, children_completed=False)
+    # 21. Push (B, children_completed=True)
+    #
+    # Finish handling B:
+    # 22. Pop (B, children_completed=True)
+    # 23. Insert token_handler(B) into A.transformed_children
+    #
+    # Finish handling A:
+    # 24. Pop (A, children_completed=True)
+    # 25. Return production_handlers[A.production](A, *A.transformed_children)
+    #
+    # It takes quite a few steps to handle even a small tree!
+    stack = [(parse_tree, None, False, None)]
+    while True:
+        node, parent, children_completed, transformed_children = stack.pop()
+        if not children_completed:
+            parent_entry = []
+            stack.append((node, parent, True, parent_entry))
+            if hasattr(node, "children"):
+                for child in node.children:
+                    stack.append((child, parent_entry, False, None))
+                if used_productions is not None:
+                    used_productions.add(node.production)
+        else:
+            if isinstance(node, parser_types.Token):
+                transformed_node = token_handler(node)
+            else:
+                transformed_node = production_handlers[node.production](
+                    *([node] + transformed_children)
+                )
+            if parent is None:
+                return transformed_node
+            else:
+                parent.insert(0, transformed_node)
diff --git a/compiler/util/test_util.py b/compiler/util/test_util.py
index d54af37..23ffa78 100644
--- a/compiler/util/test_util.py
+++ b/compiler/util/test_util.py
@@ -51,6 +51,8 @@
         name = spec.name
         field_path = "{}{}".format(path, name)
         value = getattr(proto, name)
+        if expected_values.has_field(name) and not proto.has_field(name):
+            return False, "{} missing".format(field_path)
         if spec.is_dataclass:
             if spec.is_sequence:
                 if len(expected_value) > len(value):
@@ -64,8 +66,6 @@
                     if not result[0]:
                         return result
             else:
-                if expected_values.HasField(name) and not proto.HasField(name):
-                    return False, "{} missing".format(field_path)
                 result = proto_is_superset(value, expected_value, field_path)
                 if not result[0]:
                     return result
diff --git a/compiler/util/test_util_test.py b/compiler/util/test_util_test.py
index 58e1ad6..11f4ef9 100644
--- a/compiler/util/test_util_test.py
+++ b/compiler/util/test_util_test.py
@@ -30,7 +30,7 @@
             test_util.proto_is_superset(
                 ir_data.Structure(
                     field=[ir_data.Field()],
-                    source_location=parser_types.parse_location("1:2-3:4"),
+                    source_location=parser_types.SourceLocation.from_str("1:2-3:4"),
                 ),
                 ir_data.Structure(field=[ir_data.Field()]),
             ),
@@ -42,7 +42,7 @@
             test_util.proto_is_superset(
                 ir_data.Structure(
                     field=[ir_data.Field(), ir_data.Field()],
-                    source_location=parser_types.parse_location("1:2-3:4"),
+                    source_location=parser_types.SourceLocation.from_str("1:2-3:4"),
                 ),
                 ir_data.Structure(field=[ir_data.Field()]),
             ),
@@ -53,7 +53,8 @@
             (False, "field[0] missing"),
             test_util.proto_is_superset(
                 ir_data.Structure(
-                    field=[], source_location=parser_types.parse_location("1:2-3:4")
+                    field=[],
+                    source_location=parser_types.SourceLocation.from_str("1:2-3:4"),
                 ),
                 ir_data.Structure(field=[ir_data.Field(), ir_data.Field()]),
             ),
@@ -64,25 +65,32 @@
             (False, "source_location missing"),
             test_util.proto_is_superset(
                 ir_data.Structure(field=[]),
-                ir_data.Structure(source_location=ir_data.Location()),
+                ir_data.Structure(source_location=parser_types.SourceLocation()),
             ),
         )
 
     def test_array_element_differs(self):
         self.assertEqual(
-            (False, "field[0].source_location.start.line differs: found 1, expected 2"),
+            (
+                False,
+                "field[0].source_location differs: found 1:2-3:4, expected 2:2-3:4",
+            ),
             test_util.proto_is_superset(
                 ir_data.Structure(
                     field=[
                         ir_data.Field(
-                            source_location=parser_types.parse_location("1:2-3:4")
+                            source_location=parser_types.SourceLocation.from_str(
+                                "1:2-3:4"
+                            )
                         )
                     ]
                 ),
                 ir_data.Structure(
                     field=[
                         ir_data.Field(
-                            source_location=parser_types.parse_location("2:2-3:4")
+                            source_location=parser_types.SourceLocation.from_str(
+                                "2:2-3:4"
+                            )
                         )
                     ]
                 ),
@@ -93,8 +101,12 @@
         self.assertEqual(
             (True, ""),
             test_util.proto_is_superset(
-                parser_types.parse_location("1:2-3:4"),
-                parser_types.parse_location("1:2-3:4"),
+                ir_data.Field(
+                    source_location=parser_types.SourceLocation.from_str("1:2-3:4")
+                ),
+                ir_data.Field(
+                    source_location=parser_types.SourceLocation.from_str("1:2-3:4")
+                ),
             ),
         )
 
@@ -105,17 +117,21 @@
                 ir_data.Structure(field=[ir_data.Field()]),
                 ir_data.Structure(
                     field=[ir_data.Field()],
-                    source_location=parser_types.parse_location("1:2-3:4"),
+                    source_location=parser_types.SourceLocation.from_str("1:2-3:4"),
                 ),
             ),
         )
 
     def test_optional_field_differs(self):
         self.assertEqual(
-            (False, "end.line differs: found 4, expected 3"),
+            (False, "source_location differs: found 1:2-4:4, expected 1:2-3:4"),
             test_util.proto_is_superset(
-                parser_types.parse_location("1:2-4:4"),
-                parser_types.parse_location("1:2-3:4"),
+                ir_data.Field(
+                    source_location=parser_types.SourceLocation.from_str("1:2-4:4")
+                ),
+                ir_data.Field(
+                    source_location=parser_types.SourceLocation.from_str("1:2-3:4")
+                ),
             ),
         )
 
diff --git a/compiler/util/traverse_ir.py b/compiler/util/traverse_ir.py
index 5a5ac78..7423e63 100644
--- a/compiler/util/traverse_ir.py
+++ b/compiler/util/traverse_ir.py
@@ -19,6 +19,7 @@
 from compiler.util import ir_data
 from compiler.util import ir_data_fields
 from compiler.util import ir_data_utils
+from compiler.util import parser_types
 from compiler.util import simple_memoizer
 
 
@@ -157,7 +158,7 @@
         type(proto), new_pattern[0]
     ]
     for member_name in singular_fields:
-        if proto.HasField(member_name):
+        if proto.has_field(member_name):
             _fast_traverse_proto_top_down(
                 getattr(proto, member_name),
                 incidental_actions,
@@ -219,7 +220,7 @@
     # type_to_descendant_types is a map of all types that can be reached from a
     # particular type.  After the setup, type_to_descendant_types[ir_data.EmbossIr]
     # == set(<all types>) and type_to_descendant_types[ir_data.Reference] ==
-    # {ir_data.CanonicalName, ir_data.Word, ir_data.Location} and
+    # {ir_data.CanonicalName, ir_data.Word} and
     # type_to_descendant_types[ir_data.Word] == set().
     #
     # The while loop basically ors in the known descendants of each known
diff --git a/compiler/util/traverse_ir_test.py b/compiler/util/traverse_ir_test.py
index 504eb88..05214fe 100644
--- a/compiler/util/traverse_ir_test.py
+++ b/compiler/util/traverse_ir_test.py
@@ -205,11 +205,11 @@
 
 
 def _record_kind_and_constant(constant, constant_list, type_definition):
-    if type_definition.HasField("enumeration"):
+    if type_definition.has_field("enumeration"):
         constant_list.append(("enumeration", int(constant.value)))
-    elif type_definition.HasField("structure"):
+    elif type_definition.has_field("structure"):
         constant_list.append(("structure", int(constant.value)))
-    elif type_definition.HasField("external"):
+    elif type_definition.has_field("external"):
         constant_list.append(("external", int(constant.value)))
     else:
         assert False, "Shouldn't be here."
diff --git a/doc/compiler-design.md b/doc/compiler-design.md
new file mode 100644
index 0000000..f7afb69
--- /dev/null
+++ b/doc/compiler-design.md
@@ -0,0 +1,1030 @@
+# Design of the Emboss Compiler (`embossc`)
+
+This document describes the internals of the Emboss compiler.  End users do not
+need to read this document.
+
+
+## Overall Design
+
+The Emboss compiler follows a reasonably standard compiler design, where the
+input source text is first converted to an *intermediate representation* (IR),
+then various operations are performed on the IR, and finally the IR is used to
+construct the final output — at the time of writing, C++ source code:
+
+```mermaid
+%%{init: {"flowchart": {"htmlLabels": false}} }%%
+graph LR
+    diskstart@{ shape: doc, label: "example.emb" }
+    parser["Parser"]
+    processing@{ shape: procs, label: "IR processing" }
+    backend["C++ Code Generator"]
+    diskend@{ shape: doc, label: "example.emb.h" }
+    diskstart-- ".emb" -->parser
+    parser-- IR -->processing
+    processing-- IR -->backend
+    backend-- "C++" -->diskend
+```
+
+Currently, the Emboss compiler is split into three programs: the *front end*,
+which parses the input and does almost all of the IR processing, the *C++
+back end*, which does a minimal amount of C++-specific IR processing and
+generates the final C++ code, and the `embossc` driver that combines the front
+end and back end.  This split makes it straightforward to add new back ends
+later:
+
+```mermaid
+%%{init: {"flowchart": {"htmlLabels": false}} }%%
+graph LR
+    diskstart@{ shape: doc, label: "example.emb" }
+    parser["Parser"]
+    processing@{ shape: procs, label: "IR processing" }
+    cppbackend["C++ Code Generator"]
+    cppdiskend@{ shape: doc, label: "example.emb.h" }
+    rustbackend["Rust Code Generator"]
+    rustdiskend@{ shape: doc, label: "example.emb.rs" }
+    mdbackend["Documentation Generator"]
+    mddiskend@{ shape: doc, label: "example.emb.md" }
+    diskstart-- ".emb" -->parser
+    parser-- IR -->processing
+    processing-- IR -->cppbackend
+    cppbackend-- "C++" -->cppdiskend
+    processing-- IR -->rustbackend
+    rustbackend-- Rust -->rustdiskend
+    processing-- IR -->mdbackend
+    mdbackend-- Markdown -->mddiskend
+```
+
+
+### IR (Intermediate Representation)
+
+"IR" is a general term: each compiler has its own IR.  The Emboss IR is a tree,
+with node types defined in [compiler/util/ir_data.py][ir_data_py].
+
+[ir_data_py]: ../compiler/util/ir_data.py
+
+The first stage of the compiler — the parser — generates an "initial" IR, which
+only contains information that is directly available in the source tree.  Even
+without any further information, the initial IR can be quite large even for a
+very short `.emb` file.  For example, this line:
+
+```emb
+  0  [+4]   UInt        file_state
+```
+
+turns into this IR (in JSON serialization) immediately after parsing:
+
+```json
+{
+  "location": {
+    "start": {
+      "constant": {
+        "value": "0",
+        "source_location": "22:3-22:4"
+      },
+      "source_location": "22:3-22:4"
+    },
+    "size": {
+      "constant": {
+        "value": "4",
+        "source_location": "22:8-22:9"
+      },
+      "source_location": "22:8-22:9"
+    },
+    "source_location": "22:3-22:10"
+  },
+  "type": {
+    "atomic_type": {
+      "reference": {
+        "source_name": [
+          {
+            "text": "UInt",
+            "source_location": "22:13-22:17"
+          }
+        ],
+        "source_location": "22:13-22:17"
+      },
+      "source_location": "22:13-22:17"
+    },
+    "source_location": "22:13-22:17"
+  },
+  "name": {
+    "name": {
+      "text": "file_state",
+      "source_location": "22:25-22:35"
+    },
+    "source_location": "22:25-22:35"
+  },
+  "existence_condition": {
+    "boolean_constant": {
+      "value": true,
+      "source_location": "22:3-22:35"
+    },
+    "source_location": "22:3-22:35"
+  },
+  "source_location": "22:3-22:35"
+}
+```
+
+In graphical form (with `source_location` nodes omitted for clarity):
+
+```mermaid
+graph TD
+    n0@{ shape: diamond, label: "field" }
+    n0 --> n1
+    n0 --> n4
+    n0 --> n9
+    n0 --> n10
+    n1@{ shape: diamond, label: "location" }
+    n1 --> n2
+    n1 --> n3
+    n2@{ shape: diamond, label: "start" }
+    n2 --> l0
+    n3@{ shape: diamond, label: "size" }
+    n3 --> l1
+    n4@{ shape: diamond, label: "type" }
+    n4 --> n5
+    n5@{ shape: diamond, label: "atomic_type" }
+    n5 --> n6
+    n6@{ shape: diamond, label: "reference" }
+    n6 --> n7
+    n7@{ shape: diamond, label: "source_names" }
+    n7 --> n8
+    n8@{ shape: diamond, label: "source_name" }
+    n8 --> l2
+    n9@{ shape: diamond, label: "name" }
+    n9 --> l3
+    n10@{ shape: diamond, label: "existence_condition" }
+    n10 --> l4
+    l0@{ shape: rect, label: "constant: 0" }
+    l1@{ shape: rect, label: "constant: 4" }
+    l2@{ shape: rect, label: "text: UInt" }
+    l3@{ shape: rect, label: "name: file_state" }
+    l4@{ shape: rect, label: "boolean_constant: True" }
+```
+
+This initial IR then goes through a series of *elaborations*, which annotate
+the IR, and *validations*, which check various properties of the IR.  These are implemented as *stages* in the compiler:
+
+```mermaid
+%%{init: {"flowchart": {"htmlLabels": false}} }%%
+graph LR
+    diskstart@{ shape: doc, label: "example.emb" }
+    parser["Parser"]
+    stage1@{ shape: proc, label: "Stage 1" }
+    stage2@{ shape: proc, label: "Stage 2" }
+    stages@{ shape: text, label: "..." }
+    stagenm1@{ shape: proc, label: "Stage N-1" }
+    stagen@{ shape: proc, label: "Stage N" }
+    backend["C++ Code Generator"]
+    diskend@{ shape: doc, label: "example.emb.h" }
+    diskstart-->parser
+    parser-->stage1
+    stage1-->stage2
+    stage2-->stages
+    stages-->stagenm1
+    stagenm1-->stagen
+    stagen-->backend
+    backend-->diskend
+```
+
+In many cases, elaborations and validations are mixed together — for example,
+in the symbol resolution stage, names in the IR (`field`) are *elaborated* with
+the absolute symbol to which they resolve (`module.Type.field`), and, at the
+same time, the symbol resolver *validates* that every name resolves to exactly
+one absolute symbol.
+
+At the end of this process, the IR is much larger:
+
+```mermaid
+graph TD
+    n0@{ shape: diamond, label: "field" }
+    n0 --> n1
+    n0 --> n8
+    n0 --> n15
+    n0 --> n16
+    n0 --> n19
+    n0 --> n22
+    n1@{ shape: diamond, label: "location" }
+    n1 --> n2
+    n1 --> n5
+    n2@{ shape: diamond, label: "start" }
+    n2 --> l0
+    n2 --> n3
+    n3@{ shape: diamond, label: "type" }
+    n3 --> n4
+    n4@{ shape: diamond, label: "integer" }
+    n4 --> l1
+    n4 --> l2
+    n4 --> l3
+    n4 --> l4
+    n5@{ shape: diamond, label: "size" }
+    n5 --> l5
+    n5 --> n6
+    n6@{ shape: diamond, label: "type" }
+    n6 --> n7
+    n7@{ shape: diamond, label: "integer" }
+    n7 --> l6
+    n7 --> l7
+    n7 --> l8
+    n7 --> l9
+    n8@{ shape: diamond, label: "type" }
+    n8 --> n9
+    n9@{ shape: diamond, label: "atomic_type" }
+    n9 --> n10
+    n10@{ shape: diamond, label: "reference" }
+    n10 --> n11
+    n10 --> n13
+    n11@{ shape: diamond, label: "canonical_name" }
+    n11 --> l10
+    n11 --> n12
+    n12@{ shape: diamond, label: "object_paths" }
+    n12 --> l11
+    n13@{ shape: diamond, label: "source_names" }
+    n13 --> n14
+    n14@{ shape: diamond, label: "source_name" }
+    n14 --> l12
+    n15@{ shape: diamond, label: "write_method" }
+    n15 --> l13
+    n16@{ shape: diamond, label: "name" }
+    n16 --> l14
+    n16 --> n17
+    n17@{ shape: diamond, label: "canonical_name" }
+    n17 --> l15
+    n17 --> n18
+    n18@{ shape: diamond, label: "object_paths" }
+    n18 --> l16
+    n18 --> l17
+    n19@{ shape: diamond, label: "attributes" }
+    n19 --> n20
+    n20@{ shape: diamond, label: "attribute" }
+    n20 --> l18
+    n20 --> n21
+    n20 --> l20
+    n21@{ shape: diamond, label: "value" }
+    n21 --> l19
+    n22@{ shape: diamond, label: "existence_condition" }
+    n22 --> l21
+    n22 --> n23
+    n23@{ shape: diamond, label: "type" }
+    n23 --> l22
+    l0@{ shape: rect, label: "constant: 0" }
+    l1@{ shape: rect, label: "modulus: infinity" }
+    l2@{ shape: rect, label: "modular_value: 0" }
+    l3@{ shape: rect, label: "minimum_value: 0" }
+    l4@{ shape: rect, label: "maximum_value: 0" }
+    l5@{ shape: rect, label: "constant: 4" }
+    l6@{ shape: rect, label: "modulus: infinity" }
+    l7@{ shape: rect, label: "modular_value: 4" }
+    l8@{ shape: rect, label: "minimum_value: 4" }
+    l9@{ shape: rect, label: "maximum_value: 4" }
+    l10@{ shape: rect, label: "module_file: " }
+    l11@{ shape: rect, label: "object_path: UInt" }
+    l12@{ shape: rect, label: "text: UInt" }
+    l13@{ shape: rect, label: "physical: True" }
+    l14@{ shape: rect, label: "name: file_state" }
+    l15@{ shape: rect, label: "module_file: testdata/golden/span" }
+    l16@{ shape: rect, label: "object_path: LogFileStatus" }
+    l17@{ shape: rect, label: "object_path: file_state" }
+    l18@{ shape: rect, label: "name: byte_order" }
+    l19@{ shape: rect, label: "string_constant: LittleEndian" }
+    l20@{ shape: rect, label: "is_default: False" }
+    l21@{ shape: rect, label: "boolean_constant: True" }
+    l22@{ shape: rect, label: "boolean: True" }
+```
+
+
+### Front End vs Back End(s)
+
+The Emboss compiler is divided into a front end, which does most of the work,
+and back ends, which do language-specific validations and translate the final
+IR to the final output format.  Currently, only a C++ back end exists.
+
+The compiler is structured so that the front end and back end can run as
+separate programs, and when building with [Bazel][bazel] they do run
+separately.  For efficiency, the [`embossc`][embossc_source] driver just
+imports the front end and C++ back end directly, so that it can skip the JSON
+serialization and deserialization steps.
+
+[bazel]: https://bazel.build/
+[embossc_source]: ../embossc
+
+The front end consists of (as of the time of writing) 14 stages:
+
+1.  Tokenization
+2.  Parse Tree Generation
+3.  Parse Tree → IR
+4.  Desugaring + Built-In Field Synthesis
+5.  Symbol Resolution Part 1: Head Symbols
+6.  Dependency Cycle Checking
+7.  Dependency Order Computation
+8.  Symbol Resolution Part 2: Field Access
+9.  Type Annotation
+10. Type Checking
+11. Bounds Computation
+12. Front End Attribute Normalization + Verification
+13. Miscellaneous Constraint Checking
+14. Inferred Write Method Generation
+
+Each of these stages will be explained in more detail later in this document.
+
+The C++ back end is much simpler, with only 2 stages:
+
+1. Back-End Attribute Normalization + Verification
+2. C++ Header Generation
+
+This lopsidedness is intentional: work done in the front end can be shared by
+all back ends, but work in a back end only benefits that specific back end.
+
+
+### IR Traversal
+
+Most stages walk the IR one (or more) times, processing or checking specific
+types of nodes.  The Emboss compiler uses a special
+[`fast_traverse_ir_top_down()`][traverse_ir] function that takes a *pattern*
+and calls a handler on all nodes that match that pattern.
+`fast_traverse_ir_top_down()` has been optimized to walk trees efficiently: it
+will skip branches if no node in the branch could possibly match the pattern.
+
+[traverse_ir]: ../compiler/util/traverse_ir.py#:~:def%20fast_traverse_ir_top_down
+
+For example, this will call `print()` on every `Word` in the IR:
+
+```
+fast_traverse_ir_top_down(ir, [ir_data.Word], print)
+```
+
+Or you could limit the scope to only `Word` nodes inside of `Import` nodes:
+
+```
+fast_traverse_ir_top_down(ir, [ir_data.Import, ir_data.Word], print)
+```
+
+`fast_traverse_ir_top_down()` has a lot of options.  For full usage, see
+[its documentation in the source code][traverse_ir].
+
+
+### Error Handling
+
+The general scheme for running stages is:
+
+```
+for stage in stages:
+    next_ir, errors = stage(prev_ir)
+    if errors:
+        return None, errors
+    prev_ir = next_ir
+return prev_ir, None
+```
+
+That is: run each stage, and if the stage returns any errors, stop processing
+and return the error(s).
+
+Errors are represented by lists of [messages][error_py] (`error`, `warning` or
+`note`), where, generally, the first message will be an `error` or `warning`,
+and any subsequent messages are `note` messages that provide additional
+information.
+
+[error_py]: ../compiler/util/error.py
+
+
+#### Errors on Synthetic Nodes
+
+One important caveat here is that errors on *synthetic* IR nodes — nodes that
+did not come directly from the input `.emb` — are deferred: the compiler will
+continue processing to try to find an error in a "natural" node to display to
+the user.  This is covered in more detail in [Built-In Field
+Synthesis](#desugaring).
+
+
+## Front End
+
+[*`compiler/front_end/...`*](../compiler/front_end/)
+
+The front end is responsible for reading in Emboss definitions and producing a
+normalized intermediate representation (IR).  It is divided into several steps:
+roughly, parsing, import resolution, symbol resolution, and validation.
+
+The front end is orchestrated by [`glue.py`][glue_py], which runs each front
+end component in the proper order to construct an IR suitable for consumption
+by the back end.
+
+[glue_py]: ../front_end/glue.py
+
+The front end driver program is [`emboss_front_end.py`][emboss_front_end_py],
+which calls `glue.ParseEmbossFile` and prints the results.
+
+[emboss_front_end_py]: ../front_end/emboss_front_end.py
+
+
+### Tokenization and Parsing
+
+The first part of the front end translates the text of the `.emb` input into an
+IR structure.
+
+
+#### Tokenization
+
+[*`tokenizer.py`*](../compiler/front_end/tokenizer.py)
+
+The very first stage is tokenization, also called lexical analysis or lexing.
+Tokenization breaks the input text into *tokens* of one or more characters.
+For example, take the string `abc+def`:
+
+```
++---+---+---+---+---+---+---+
+| a | b | c | + | d | e | f |
++---+---+---+---+---+---+---+
+```
+
+This will be grouped into three tokens, `abc`, `+`, and `def`:
+
+```
++-----------+-----+-----------+
+|    abc    |  +  |    def    |
+| SnakeWord | "+" | SnakeWord |
++-----------+-----+-----------+
+```
+
+In addition, each token is labeled with a category, such as `Documentation`,
+`Number`, or `"*"`: by convention, tokens that are always a specific sequence
+of characters are given a label that is just the token in double quotes, such
+as `"+"` for `+`, `"=="` for `==`, `"if"` for `if`, and so on.
+
+These category labels match names in the grammar in the next step.
+
+There is one extra bit of logic in the Emboss tokenizer, which mimics CPython:
+indentation is tracked and translated into special `Indent` and `Dedent`
+tokens when it changes.  This fragment:
+
+```emb
+struct Foo:
+  -- word
+```
+
+will be tokenized as:
+
+```
++----------+-----------+-----+------+--------+---------------+--------+
+|  struct  |    Foo    |  :  |  \n  |        |    -- word    |        |
+| "struct" | SnakeName | ":" | "\n" | Indent | Documentation | Dedent |
++----------+-----------+-----+------+--------+---------------+--------+
+```
+
+
+#### Parse Tree Generation
+
+[*`lr1.py`*](../compiler/front_end/lr1.py)
+
+The list of tokens is then passed to a parser, which produces a parse tree.
+The point of this stage is to take the list of tokens, and apply a tree
+structure on top of it.  Starting with the tokens from the previous example:
+
+```mermaid
+graph LR
+    colon@{label: "\":\""}
+    newline@{label: "\"\\n\""}
+    struct ~~~ Foo ~~~ colon ~~~ newline ~~~ Indent ~~~ Documentation ~~~ Dedent
+```
+
+the parser infers the parse tree:
+
+```mermaid
+graph TD
+        r0@{shape: diamond, label: "module"}
+        r1@{shape: diamond, label: "comment-line*"}
+        r2@{shape: diamond, label: "doc-line*"}
+        r3@{shape: diamond, label: "import-line*"}
+        r4@{shape: diamond, label: "attribute-line*"}
+        r5@{shape: diamond, label: "type-definition*"}
+        r6@{shape: diamond, label: "type-definition"}
+        r7@{shape: diamond, label: "struct"}
+        r8@{shape: diamond, label: "type-name"}
+        r9@{shape: diamond, label: "type-word"}
+        r10@{shape: diamond, label: "delimited-parameter-definition-list?"}
+        r11@{shape: diamond, label: "Comment?"}
+        r12@{shape: diamond, label: "eol"}
+        r13@{shape: diamond, label: "comment-line*"}
+        r14@{shape: diamond, label: "struct-body"}
+        r15@{shape: diamond, label: "doc-line*"}
+        r16@{shape: diamond, label: "doc-line"}
+        r17@{shape: diamond, label: "doc"}
+        r18@{shape: diamond, label: "Comment?"}
+        r19@{shape: diamond, label: "eol"}
+        r20@{shape: diamond, label: "comment-line*"}
+        r21@{shape: diamond, label: "doc-line*"}
+        r22@{shape: diamond, label: "attribute-line*"}
+        r23@{shape: diamond, label: "type-definition*"}
+        r24@{shape: diamond, label: "struct-field-block"}
+        r25@{shape: diamond, label: "type-definition*"}
+    subgraph tokens
+        direction LR
+        t0@{shape: rect, label: "struct"}
+        t1@{shape: rect, label: "Foo"}
+        t2@{shape: rect, label: ":"}
+        t3@{shape: rect, label: "\\n"}
+        t4@{shape: rect, label: "Indent"}
+        t5@{shape: rect, label: "-- word"}
+        t6@{shape: rect, label: "\\n"}
+        t7@{shape: rect, label: "Dedent"}
+    end
+    r0 --> r1
+    r0 --> r2
+    r0 --> r3
+    r0 --> r4
+    r0 --> r5
+    r5 --> r6
+    r5 --> r25
+    r6 --> r7
+    r7 ----> t0
+    r7 --> r8
+    r7 --> r10
+    r7 ----> t2
+    r7 --> r11
+    r7 --> r12
+    r7 --> r14
+    r8 --> r9
+    r9 ----> t1
+    r12 ----> t3
+    r12 --> r13
+    r14 ----> t4
+    r14 --> r15
+    r14 --> r22
+    r14 --> r23
+    r14 --> r24
+    r14 ----> t7
+    r15 --> r16
+    r15 --> r21
+    r16 --> r17
+    r16 --> r18
+    r16 --> r19
+    r17 ----> t5
+    r19 ----> t6
+    r19 --> r20
+```
+
+Parsing is a large subject with many good tutorials and references available,
+so only the `embossc` specifics are covered here.
+
+The Emboss compiler uses a [shift-reduce (also known as "LR(1)")
+parser][shift_reduce], using a [custom engine][lr1_py] that has some features
+that are not available in most other shift-reduce engines — and also some
+limitations.
+
+[shift_reduce]: https://en.wikipedia.org/wiki/Shift-reduce_parser
+[lr1_py]: ../compiler/front_end/lr1.py
+
+The biggest limitation is that the table generator only implements the
+[canonical LR(1)][canonical_lr1] table generation algorithm, which means that
+there is no "side channel" way of specifying precedence or otherwise resolving
+conflicts — shift/reduce and reduce/reduce conflicts must be resolved by
+removing them from the grammar.  (However, Emboss's grammar uses
+partially-ordered precedence, which — as far as the author is aware — is not
+supported by any off-the-shelf precedence system.)
+
+[canonical_lr1]: https://doi.org/10.1016/S0019-9958(65)90426-2
+
+The biggest unusual feature is the incorporation of a [*Merr*][merr]-like
+system for error messages.
+
+[merr]: https://doi.org/10.1145/937563.937566
+
+The output from this stage is a *parse tree*, not an IR.
+
+
+#### Parse Tree → IR
+
+[*`module_ir.py`*](../compiler/front_end/module_ir.py)
+
+Finally, the parse tree is transformed into an IR.  This is mostly a
+straightforward translation, but there are a few places where the parse tree is
+noticeably different from the IR.  For example, in the parse tree, lists are
+explicit *cons* lists, like:
+
+```mermaid
+graph TD
+    r1@{label: "struct-field-block"}
+    r2@{label: "struct-field*"}
+    r3@{label: "struct-field"}
+    r4@{label: "struct-field*"}
+    r5@{label: "struct-field"}
+    r6@{label: "struct-field*"}
+    r7@{label: "struct-field"}
+    r8@{label: "struct-field*"}
+    r1 --> r2
+    r2 --> r3
+    r2 --> r4
+    r4 --> r5
+    r4 --> r6
+    r6 --> r7
+    r6 --> r8
+```
+
+while in the IR these lists are flattened:
+
+```mermaid
+graph TD
+    n0@{label: "structure"}
+    n1@{label: "fields"}
+    n2@{label: "field"}
+    n3@{label: "field"}
+    n4@{label: "field"}
+    n0 --> n1
+    n1 --> n2
+    n1 --> n3
+    n1 --> n4
+```
+
+One bit of pure syntax sugar that is handled at this stage is chained
+comparisons: `a == b == c` will be translated to the IR equivalent of `a == b
+&& b == c`.
+
+
+### IR Processing
+
+<a name="desugaring"></a>
+
+#### Desugaring + Built-In Field Synthesis
+
+[*`synthetics.py`*](../compiler/front_end/synthetics.py)
+
+The first stage that operates on the IR adds built-in fields like
+`$size_in_bytes` and rewrites some constructs to a more regular form.
+Specifically, anonymous `bits` will be rewritten into non-anonymous `bits`, and
+`$next` will be replaced with the offset + size of the previous field.
+Starting with this:
+
+```emb
+struct Foo:
+    0 [+4]  bits:
+        0  [+1]  Flag  low
+        31 [+1]  Flag  high
+    if low:
+        $next [+4]  UInt  field
+```
+
+`synthetics.py` will rewrite the IR into (the equivalent of):
+
+```emb
+struct Foo:
+    bits EmbossReservedAnonymous0:
+        [text_output: "Skip"]
+        0  [+1]  Flag  low
+        31 [+1]  Flag  high
+    let $size_in_bytes = $max(0, true ? 0+4 : 0, low ? (0+4)+4 : 0)
+    let $max_size_in_bytes = $upper_bound($size_in_bytes)
+    let $min_size_in_bytes = $lower_bound($size_in_bytes)
+    0 [+4]  EmbossReservedAnonymous0  emboss_reserved_anonymous_1
+    if low:
+        0+4 [+4]  UInt  field
+    let low = emboss_reserved_anonymous_1.low
+    let high = emboss_reserved_anonymous_1.high
+```
+
+One important detail is that the newly-created nodes are marked as *synthetic*.
+This makes a difference for error handling: because of the way that some of the
+synthetic nodes are constructed from copied pieces of existing IR, errors can
+sometimes be detected in synthetic nodes before they are detected in the
+original source nodes they were copied from.  These errors tend to be very
+confusing to end users, since they reference parts of the IR that were not
+entered by an end user.  For example, the incorrect:
+
+```emb
+struct Foo:
+    false [+4]  UInt  field
+```
+
+will have a synthesized `$size_in_bytes` field:
+
+```emb
+struct Foo:
+    let $size_in_bytes = $max(0, true ? false+4 : 0)
+    false [+4]  UInt  field
+```
+
+The erroneous expression `false+4` will be detected before the top-level type
+error of using `false` as the field offset, with a message like:
+
+```
+example.emb:2:5: error: Left argument of operator '+' must be an integer.
+    false [+4]  UInt  field
+    ^^^^^
+```
+
+To avoid confusing end users, any error with a synthetic location will be
+*deferred*, and only shown to an end user if no non-synthetic errors are
+encountered during IR processing.  In this case, the correct error message will
+be found and displayed to the end user:
+
+```
+example.emb:2:5: error: Start of field must be an integer.
+    false [+4]  UInt  field
+    ^^^^^
+```
+
+
+#### Symbol Resolution Part 1: Head Symbols
+
+[*`symbol_resolver.py`*](../compiler/front_end/symbol_resolver.py)
+
+After desugaring, the first part of symbol resolution occurs: resolving *head*
+symbols.  Head symbols are any symbols that do not follow a `.`: for example,
+`head` or `Head` in `head`, `Head.field` and `head.Type.field`.  Resolution of
+symbols after `.` happens in a later stage, after some other checking.
+
+Head symbol resolution follows lexical scoping rules: a symbol may refer to
+entities in a set of *scopes* determined by their position in the source text.
+
+Head symbol resolution is straightforward: while walking down the IR tree,
+build up a list of available scopes.  When a symbol is encountered, check to
+see if that symbol is *defined* in any of the available scopes.  If it is
+defined in *exactly one* available scope, bind the symbol to that definition.
+If it is not defined, raise an error.  Emboss takes the unusual step of *also*
+raising an error if the symbol is defined in two or more scopes: in most
+computer languages, there is some scope precedence, and the highest-precedence
+definition is used.  However, this can lead to surprising, and in some cases
+*silently incorrect* results when the desired definition is *shadowed* by an
+unknown-to-the-user higher-precedence definition, so Emboss raises an error and
+requires the user to explicitly pick the correct definition.
+
+
+#### Dependency Cycle Checking
+
+[*`dependency_checker.py`*](../compiler/front_end/dependency_checker.py)
+
+Once head symbols have been resolved, there is enough information in the IR to
+check for cycles in the dependency graph: cases where `object_1` depends on
+`object_2` and `object_2` also depends on `object_1`, sometimes through a chain
+of multiple dependencies.
+
+The Emboss compiler accomplishes this by first building up the complete
+dependency graph of the IR, and then running a graph partitioning algorithm
+([Tarjan's algorithm][tarjan], in this case) on the dependency graph to find
+all strongly-connected components.  If there are any partitions with more than
+one node, or any nodes with a self edge, then there is a dependency cycle.
+
+[tarjan]: https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
+
+
+#### Dependency Order Computation
+
+[*`dependency_checker.py`*](../compiler/front_end/dependency_checker.py)
+
+Every structure in the IR is also annotated with a 'dependency ordering': an
+ordering of its fields such that any field *A* that depends on another field
+*B* is later in the ordering than *B*.
+
+This ordering is not used until the back end (where it is used to order fields
+for text output), but it is convenient to build it here, where the dependency
+graph has already been built.
+
+
+#### Symbol Resolution Part 2: Field Access
+
+[*`symbol_resolver.py`*](../compiler/front_end/symbol_resolver.py)
+
+Next, "tail" symbols are resolved: any symbol immediately after `.`.  These are
+resolved after checking for dependency cycles because the resolution algorithm
+can become stuck in infinite recursion if there is a dependency cycle.
+
+
+#### Type Annotation
+
+[*`type_check.py`*](../compiler/front_end/type_check.py)
+
+With symbols resolved, it is possible to annotate expression types.  The Emboss
+compiler annotates *every* expression and subexpression with a type: at this
+stage, those types are coarse: integer, enum, boolean, string, "opaque", etc.
+
+This stage also checks expressions for *internal* type consistency.  For
+example, it will find the error in:
+
+```emb
+struct Foo:
+    let a = 10 + true
+```
+
+but not in:
+
+```emb
+struct Foo:
+    true [+4]  UInt  a
+```
+
+
+#### Type Checking
+
+[*`type_check.py`*](../compiler/front_end/type_check.py)
+
+After annotating all types, the compiler checks that expressions have the
+correct top-level types: that is, that their types are correct for their
+positions within the IR.  This is the stage that detects the use of a boolean
+as a field offset from the previous example:
+
+```emb
+struct Foo:
+    true [+4]  UInt  a
+```
+
+
+#### Bounds Computation
+
+[*`expression_bounds.py`*](../compiler/front_end/expression_bounds.py)
+
+With coarse type checking done, the expression types can be *refined* into
+narrower types: for example, instead of just "integer," "integer between 0 and
+65535, inclusive."
+
+Fully understanding this stage involves (just a tiny bit!) of Type Theory:
+mainly, that a "type" in the computer science sense is just a *set* (in the
+mathematical sense) of all the values that a variable of that type could
+possibly hold.  This sort of "type" is conflated with physical layout in most
+industrial computing languages (including Emboss), but is conceptually
+separate.
+
+The boolean type is the set $\left\\{ \scriptstyle{FALSE}, \scriptstyle{TRUE}
+\right\\}$, so its only refinements (nonempty subsets) are $\left\\{
+\scriptstyle{FALSE} \right\\}$ and $\left\\{ \scriptstyle{TRUE} \right\\}$.
+This stage will try to make those refinements, where possible.
+
+The base integer type in the Emboss expression language is the set of all
+integers, normally written as $\mathbb{Z}$.  It is obviously impossible for any
+real-world computer to have a variable of type $\mathbb{Z}$ — there is no
+computer with infinite memory — so this type needs to be refined.
+
+In Emboss, currently, integer types are refined into the form $\left\\{ x | x
+\in \mathbb{Z} \wedge a \le x \le b \wedge x \equiv n \pmod m \right\\}$: that
+is, $x$ is an integer ($x \in \mathbb{Z}$), $x$ is at least $a$ and at most $b$
+($a \le x \le b$), and $x$ % $m$ == $n$ ($x \equiv n \pmod m$).  The values $a$
+and $b$ are lower and upper bounds, respectively, while $m$ and $n$ are used
+for alignment tracking — $m$ tracks the "level" of alignment, and $n$ tracks
+the "offset" within the alignment.
+
+This integer type refinement starts with known types.  A value read from an
+`Int` or `UInt` field will have known bounds (based on the bit width of the
+field), $m = 1$ and $n = 0$.  A constant $c$ has $a = b = n = c$ and $m =
+\infty$.
+
+From this basis, the refinements for any operations can be determined.  For
+example, for `x + y`, the resulting lower and upper bounds $a = a_x + a_y$ and
+$b = b_x + b_y$.  The resulting alignment is a little more complex, involving
+the greatest common divisor function.
+
+The Emboss functions `$lower_bound(x)` and `$upper_bound(x)` are a little
+strange: their result is a constant that is the lower or upper bound
+(respectively) of their argument!  That is, they extract a value from the type
+system and return it as an expression.  There aren't a lot of human-authored
+uses of these functions, but they are used in the definitions of fields like
+`$min_size_in_bytes` and `$max_size_in_bits`.
+
+The refinements that Emboss finds are not always perfectly optimal, for various
+reasons: for example, even if $x < 0$, `x * x` cannot be negative, but Emboss
+does not try to detect any *cross-argument constraints*, so it will not figure
+this out.
+
+It might be tempting to add better refinement to Emboss, but there are
+downsides.  First, new refinements take up compiler time, which can contribute
+to slow builds.  Many possible refinements would only be found on a tiny
+fraction of all expressions, so it is not worth the compiler time to search for
+them.
+
+Second, and probably more importantly, any new refinements become part of the
+Emboss contract with end users, forever: `$upper_bound()` must never return a
+larger value than it did in previous versions, and `$lower_bound()` must never
+return a smaller value.  Reduced alignment bounds can cause performance
+regressions in the highest-performance code.  This has direct implications for
+maintainence of the current Emboss compiler, but it also makes it even harder
+for any third-party compiler to fully implement Emboss — which, in turn, means
+that Emboss is even more likely to be a single-vendor language, like Python or
+Ruby, instead of a multi-vendor language like C++ or JavaScript.
+
+
+#### Front End Attribute Normalization + Verification
+
+[*`attribute_checker.py`*](../compiler/front_end/attribute_checker.py`)
+
+This stage checks the attributes (annotations like `[byte_order:
+"LittleEndian"]`) that are used by the Emboss front end, and adds missing
+attributes where needed.
+
+Attributes were originally intended to be a way to add functionality without
+having to add new syntax, so their semantics are not conceptually cohesive.
+Nonetheless, they are all handled together in the same stage.
+
+This stage checks that all attributes have the correct argument type (no
+`[byte_order: 10]`) and that their values are valid (no `[byte_order:
+"scrambled"]`).  `$default`'ed attributes have their values copied into every
+place in the IR where they make sense and were not overridden (so `[$default
+byte_order: "BigEndian"]` will cause `[byte_order: "BigEndian"]` to be attached
+to most fields that do not already have a `[byte_order]` attribute).
+
+
+#### Miscellaneous Constraint Checking
+
+[*`constraints.py`*](../compiler/front_end/constraints.py)
+
+Even more conceptually incoherent than the previous stage, constraint checking
+verifies that certain things are true about the IR:
+
+*   Fields in `bits` have types that are allowed in `bits`.
+*   Arrays have constant sizes for all dimensions other than the last one,
+    which may be empty.
+*   Arrays in `struct` are arrays of types that are a whole number of bytes
+    long (no `UInt:4[]`).
+*   In `T[]`, `T` has a constant size.
+*   That fields with `external` types like `Int`, `Flag`, etc. meet the
+    requirements for those types, in terms of size.
+*   That enum, field, and type names are not reserved words in any existing
+    mainstream programming language as of 2014, even if they are not Emboss
+    keywords.  For example, no field may be named `class`, even though Emboss
+    does not care.
+*   That constant references (references of the form `Type.field`) are actually
+    constant.
+*   That all enum values can be represented as 64-bit unsigned or signed
+    2's-complement integers (or narrower, if the `enum` has an explicit,
+    narrower width).
+*   That all expression values *that might be computed at runtime* fit within
+    64-bit unsigned or signed 2's-complement integers.
+
+The common theme of these is that they are not used anywhere in the front end,
+but they simplify the back end by reducing the cases that have to be handled.
+
+Most of these constraints could be lifted at some point.
+
+
+#### Inferred Write Method Generation
+
+[*`write_inference.py`*](../compiler/front_end/write_inference.py)
+
+This stage — the last before the IR goes to the band end — figures out how to
+write through virtual fields.  There are three possibilities:
+
+If the virtual field is a direct alias (`let field = some_other_field`), then
+writing through `field` is exactly the same as writing through
+`some_other_field`.  In fact, it is *so* exactly the same that the C++ back end
+handles this by making the `field()` method call just return the view of
+`some_other_field()` directly.  This works even if `some_other_field` is
+actually a nested field, like `some.other.field`.
+
+This method is most important for anonymous `bits`: it is important to be able
+to write through the aliases because the original field is not accessible to
+end users.
+
+If the virtual field is a series of additions and subtractions on exactly one
+other field, like `let f_plus_10 = f + 10`, then a special "write" expression
+will be generated that inverts the calculation: in this case, `f_plus_10 - 10`.
+It was the intention of the Emboss authors to expand this inference over time,
+but (currently) addition and subtraction are the only fully-invertible
+operations in the Emboss expression language.
+
+Lastly, if neither of the other options apply, the field is read-only.
+
+It was also the intention to open this feature up to users by allowing "write
+method" attributes to be attached to virtual fields, like:
+
+```emb
+# An example from an actual device, where `x` is a frequency expressed in
+# either Hz or MHz.
+let f = x < 1000 ? x * 1000000 : x
+    [write_field: x]
+    [write_expression: value]
+```
+
+
+## C++ Back End
+
+[*`compiler/back_end/cpp`*](../compiler/back_end/cpp)
+
+The C++ back end transforms the fully elaborated IR into a header file.
+
+
+### C++ Back-End Attribute Verification
+
+[*`attributes.py`*](../compiler/back_end/cpp/attributes.py)
+
+[*`header_generator.py`*](../compiler/back_end/cpp/header_generator.py)
+
+The first stage of the C++ back end is a short one: it verifies that the
+`[(cpp) namespace]` attribute, if present, is a valid C++ namespace, and that
+any `[(cpp) enum_case]` attributes are valid.
+
+
+### C++ Header Generation
+
+[*`header_generator.py`*](../compiler/back_end/cpp/header_generator.py)
+
+The very last stage walks the IR and produces the text of a C++ `.h` file.
+
+Unlike most stages, C++ header generation does *not* use
+`fast_traverse_ir_top_down()`: the code to walk the tree is manual, generally
+assembling fragments of C++ code from the bottom up.
+During most steps of this traversal, the C++ back end builds up three separate
+sections: a forward declaration section, a class definition section, and then a
+method definition section, which are eventually emitted in that specific order.
+This structure lets any circular references (e.g., Emboss structure types that
+mutually contain each other) work without the back end having to track anything
+special: by the time a type is referenced, it will always have been declared,
+and by the time a type is actually *used* it will always have been defined.
+
+This stage has the most code of any single stage of the Emboss compiler, so it
+can be difficult to follow.  (It is also some of the oldest code in the
+compiler, which does not help.)
diff --git a/doc/contributing.md b/doc/contributing.md
new file mode 100644
index 0000000..8074449
--- /dev/null
+++ b/doc/contributing.md
@@ -0,0 +1,165 @@
+# Contributing to Emboss
+
+If you would like to fix a bug or add a new feature to Emboss, great!  This
+document is intended to help you understand the procedure, so that your change
+can land in the main Emboss repository.
+
+You do not have to take a change all the way from start to finish, either: if
+you can get a design approved, then someone else can implement it much more
+easily.  Conversely, if you are looking for a way to help, you might look for
+existing [feature
+requests](https://github.com/google/emboss/labels/enhancement) that have
+designs or at [open design sketches](design_docs/) that you might be able to
+implement.
+
+
+## All Changes
+
+Because Emboss is a Google project, in order to submit code you will need to
+sign a [Google Contributor License Agreement
+(CLA)](https://cla.developers.google.com/).
+
+**IMPORTANT**: if your contribution includes code that is not covered by a
+Google CLA and is not owned by Google, the Emboss project has to follow special
+procedures to include it.  Please let us know ([filing an issue on
+GitHub](https://github.com/google/emboss/issues/new) is probably the easiest
+way) so that we can walk you through the process.  In particular, we generally
+cannot accept any code from StackExchange or similar sites, and any code that
+comes from a non-Google open source project needs to have an acceptable license
+and be committed to the Emboss repository in a specific location.
+
+
+### Updating Build Helper Files
+
+The Emboss project provides a set of generated files in the `gen/` directory
+that can be used by other build systems (like CMake, GN, etc.) to easily
+include the Emboss compiler and C++ runtime sources.
+
+These files are generated from a single source of truth: `build.json`.
+
+-   **`build.json`**: This file, located in the project root, contains the
+    canonical lists of source files required for the compiler and the C++
+    runtime. It is the only file in this system that should be manually
+    edited, though it is typically updated via a script.
+
+-   **`gen/`**: This directory contains the generated helper files. **Do not
+    edit these files directly**, as they will be overwritten.
+
+If you change the dependencies of the Emboss compiler or runtime in the Bazel
+build system, you will need to update `build.json` and regenerate the helper
+files.
+
+-   To update `build.json` with the latest sources from Bazel, run:
+    ```bash
+    ./scripts/build_helpers/manage_build_json.py
+    ```
+
+-   To regenerate the files in `gen/` after modifying `build.json`, run:
+    ```bash
+    ./scripts/build_helpers/generate_build_files.py
+    ```
+
+A CI check is in place to ensure that `build.json` is always in sync with the
+Bazel build. If this check fails, you will need to run the `manage_build_json.py`
+script and commit the changes.
+
+
+### How-To Guides
+
+This document covers the process of getting a change into the main Emboss
+repository — i.e., what you need to do to get your change into
+[the main Emboss repository](https://github.com/google/emboss/).
+
+[How to Implement Changes to Emboss](how-to-implement.md) has an overview of
+how to make code changes to Emboss.
+
+[How to Design Features for Emboss](how-to-design.md) has an overview of what
+to think about during your design.
+
+
+### Bug Fixes vs New Features
+
+The general process for bug fixes and new features is the same, but bug fixes
+usually require less design work, and therefore can go through lighter
+processes.
+
+
+## Very Small Changes
+
+If you have a tiny change — for example,  making a fix that does not change the
+design of `embossc` — you can jump directly into coding.
+
+This process works best if your change is small and not likely to be
+controversial, or if you have already completed [the steps for small
+changes](#small-changes).
+
+1.  [Code up your proposed change](how-to-implement.md) and open a [pull
+    request
+    (PR)](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request)
+    to [the main Emboss repository](https://github.com/google/emboss/).  If you
+    have not completed [the steps for small changes](#small-changes), this
+    gives the Emboss maintainers something more concrete to look at, but you
+    may end up doing more work if your initial proposal turns out to be the
+    wrong approach.
+
+2.  The Emboss maintainers will review your PR, and may request changes.  Don't
+    be discouraged if your PR is not immediately accepted — even PRs that
+    maintainers send to each other often have requests for changes!  We want
+    the Emboss code to be high-quality, which means helping you make your code
+    better.
+
+3.  Once your PR reaches a point where it is good enough, an Emboss maintainer
+    will merge it into the Emboss repository.
+
+
+## Small Changes
+
+If your change is small, but still requires some design work — for example,
+adding a new utility function in the C++ runtime library, or making a bug fix
+that involves re-structuring some of the `embossc` code — it is usually best to
+get some feedback before you start coding.
+
+1.  [File an issue on GitHub](https://github.com/google/emboss/issues/new), if
+    there is not an issue already.  It is best to use the *problem you want to
+    solve* for the issue title and description, and then propose your design in
+    a comment.
+
+2.  Once the Emboss maintainers have had a chance to review your proposal and
+    agree on the general outline, follow [the procedure for very small
+    changes](#very-small-changes).
+
+
+## Medium and Large Changes
+
+If you have a medium or large change — for example, introducing a new pass in
+`embossc`, adding a new data type, adding a new operator to the Emboss
+expression language, making a cross-cutting refactoring of `embossc`, etc. —
+then you should start by writing a *design sketch*.
+
+A design sketch is, basically, an informal design doc — it covers the topics
+that a design doc would cover, but may have open questions or alternatives that
+haven't been locked down.
+
+1.  [File an issue on GitHub](https://github.com/google/emboss/issues/new), if
+    there is not an issue already.  It is best to use the *problem you want to
+    solve* for the issue title and description.
+
+2.  Look at [existing design sketches](design_docs/) and [archived design docs
+    for changes that have already landed](design_docs/archive/) to get a feel
+    for what should be in a design sketch.
+
+3.  If you have not already done so, read [How to Design Features for
+    Emboss](how-to-design.md).
+
+4.  Write a draft design sketch for your change, and open a pull request
+    against [the main Emboss repository](https://github.com/google/emboss/).
+
+5.  It is very likely that your design sketch will need revision before it is
+    accepted.  If it does, do not be discouraged — we want your change to
+    succeed!
+
+6.  Once your design sketch has been accepted, you can move on to
+    implementation, following (more or less) the same procedure you would
+    follow for [small](#small-changes) or [very small
+    changes](#very-small-changes).  Depending on the complexity of the change,
+    you may need to split your implementation into multiple changes.
diff --git a/doc/cpp-dark-corners.md b/doc/cpp-dark-corners.md
new file mode 100644
index 0000000..f8b0d9c
--- /dev/null
+++ b/doc/cpp-dark-corners.md
@@ -0,0 +1,701 @@
+# C++ Dark Corners
+
+Emboss is intended to protect end users from C++, to the extent that that is
+possible.  Further, because Emboss code gets imported into end user projects,
+it may be used in situations that are difficult to anticipate.  Because of
+this, Emboss C++ contributors need to be much more aware of edge cases in C++
+than the typical C++ programmer.
+
+
+## A Short Defense of C++
+
+C++ is an *old* language, with nearly-perfect backwards compatibility to the
+original *C*89 standard — more than 35 years, as of the time of writing! — and
+that is a long time to acquire... quirks.  Many (though not all) of the dark
+corners in C++23 originated in C89 (or, more realistically, in K&R C, which
+dates back to 1972).
+
+The computing world of the 1970s, 1980s, and into the 1990s was significantly
+different than the computing world of the 2010s or 2020s: between 1995 and
+2015, a premium desktop computer got approximately 200 times faster, with
+around 200 times as much RAM and 2000 times as much storage — many compiler
+checks and optimizations were computationally infeasible in 1995, much less
+1989 or 1972.  The field of Software Engineering also advanced significantly,
+as professional programmers learned how to design programs and languages to
+minimize programmer errors.
+
+All of this is to say: C++ was originally designed in a time when many of the
+things we now take for granted were completely unknown.
+
+Of course, that does not automatically excuse those dark corners existing in
+C++23 — C++ is an evolving language, after all.  However, the C++ standards
+committee has to balance many competing interests: backwards compatibility
+remains extremely important in C++, *including* for performance.  Nonetheless,
+the committee has managed to clean things up in most of the standards.  For
+example:
+
+*    C++17: dropped [trigraphs][trigraphs], and changed the rules for
+     unsigned-to-signed casts such that `static_cast<signed>(MAX_UINT)` is
+     always `== -1`
+*    C++20: cleaned up the rules for shifts; `-10 << 1 == -20` instead of
+     undefined behavior
+*    C++23: allows whitespace after `\` at the end of a line
+*    C++26: automatic memory initialization by default (`int x; f(x);` is no
+     longer undefined).
+
+[trigraphs]: https://en.cppreference.com/w/cpp/language/operator_alternative#Trigraphs_.28removed_in_C.2B.2B17.29
+
+
+## Types of Dark Corners
+
+C++ has four basic categories of behavior to watch out for:
+
+1.  Undefined behavior
+2.  Implementation-defined behavior
+3.  Standard quirks
+4.  C++-as-implemented
+
+
+### Undefined Behavior
+
+Undefined behavior is the class of "dark corners" that gets, by far, the most
+attention in the wider world, so I will not go into too much detail here.
+[John Regehr's introduction on the subject][regehr_ub] provides a good
+overview.
+
+[regehr_ub]: https://blog.regehr.org/archives/213
+
+The short version is that if your program ever performs what the standard calls
+"undefined behavior," (often shortened to "UB" in the wider world) your program
+is not *and never was* a C++ program, according to the standard, and therefore
+*none of the guarantees in the standard apply*.
+
+If you invoke undefined behavior, the compiler is allowed to do *anything*: it
+can do exactly what you would naïvely expect, it can format your hard drive, it
+can emit a program that formats your hard drive, or anything in between.  This
+uncertainty combined with danger (sometimes your use of undefined behavior Just
+Works, at least until a new compiler version shows up and turns your working
+code into a [security vulnerability][cve_2009_1897]) makes undefined behavior
+the most dangerous type of dark corner in C++.
+
+[cve_2009_1897]: https://nvd.nist.gov/vuln/detail/CVE-2009-1897
+
+Examples of undefined behavior in C++ include dereferencing `nullptr` or
+reading uninitialized memory.
+
+This document covers a number of specific types of undefined behavior,
+including some categories that do not get a lot of attention in the wider world
+of C++ development.
+
+
+### Implementation-Defined Behavior
+
+In addition to the "undefined" class of behaviors, the C++ standard has a class
+of "implementation-defined behavior," where a conforming C++ compiler has to
+have well-defined behavior, but the exact behavior is up to each compiler
+implementation (where "implementation" means a particular version of a compiler
+used with a specific set of options and targetting a specific platform —
+though, in practice, compilers tend to have mostly stable
+implementation-defined behavior between *versions*).
+
+Some cases of implementation-defined behavior are well-known among C++
+developers: for example, the size of `long` varies between 32 and 64 bits on
+common platforms (but the latest C++ standard only specifies that `long` is at
+least 32 bits — a conforming implementation could, for example, have 128-bit
+`long` or 48-bit `long`).
+
+Implementation-defined behavior is tricky for Emboss because it tends to be
+stable on a single platform, but vary between platforms — sometimes only on
+relatively obscure platforms.  This kind of issue is difficult to catch through
+automated testing — you would need to run the test suite tens of thousands of
+times, on every compiler on every platform with every set of valid compiler
+flags.  This is infeasible, even for very large teams.
+
+For example, most or all Itanium compilers defined unsigned-to-signed casts to
+return 0 if the high bit of the unsigned value was 1, at least until C++17
+standardized 2's-complement casting.  Emboss has never (to the Emboss authors'
+knowledge) been used on Itanium, and we have no intention of setting up an
+Itanium testing environment (even if we could find an Itanium-based machine to
+do so!).
+
+
+### Standard Quirks
+
+C++ also has various behaviors that are fully-defined, but surprising to most
+developers.  For example, the ["digraph" alternative operator
+representations][cppreference_alternative_operator_representations]:
+
+[cppreference_alternative_operator_representations]: https://en.cppreference.com/w/cpp/language/operator_alternative
+
+| Primary | Alternative |
+| ------- | ----------- |
+| `{`     | `<%`        |
+| `}`     | `%>`        |
+| `[`     | `<:`        |
+| `]`     | `:>`        |
+| `#`     | `%:`        |
+
+The "alternative" representations can be freely used in place of the "primary"
+representations.  These two code snippets are exactly equivalent in standard
+C++:
+
+```c++
+#include <string>
+#include <vector>
+int f(const std::vector<int> &v) {
+  return v[0];
+}
+```
+
+```c++
+%:include <string>
+%:include <vector>
+int f(const std::vector<int> &v) <%
+  return v<:0:>;
+%>
+```
+
+Alternative representations do not have to be used consistently.  This is also
+equivalent in C++ (but many editors and IDEs will complain about the "unclosed"
+brace and "unopened" bracket!):
+
+```c++
+%:include <string>
+#include <vector>
+int f(const std::vector<int> &v) {
+  return v<:0];
+%>
+```
+
+
+### C++-as-Implemented
+
+The final category of C++ dark corners is where the lofty theory of the C++
+standard meets the messiness and imperfection of the real world: there is no
+C++ compiler that perfectly and *only* implements any version of the C++
+standard.  The differences between standard and practice fall into two
+categories:
+
+
+#### Compiler Bugs
+
+Emboss currently has workarounds for four (4) verified compiler bugs in its
+code base, and it is likely that it is affected by others.  One of the known
+bugs results in silent miscompilation — in certain circumstances, client code
+using Emboss would return incorrect results, with no diagnostic message from
+the compiler (luckily, this was discovered by Emboss's test suite).
+
+In theory, Emboss is only required to work on *correct* C++ compilers, but in
+practice we want it to work on (at least) all the common C++ compilers, even
+though those compilers have bugs.
+
+
+#### Vendor Extensions
+
+All major compiler vendors implement their own extensions on top of the C++
+standard — features that *that vendor* guarantees, but which are not part of
+the standard and which other compilers may or may not support.
+
+Most of the time, these do not affect Emboss development, but sometimes they
+can be useful — if used judiciously, with fallbacks for compilers that do not
+support them.
+
+A trivial example of a vendor extension is that `$` is allowed in identifiers
+on every major compiler (and almost every tool that processes C++ source code),
+albeit with a warning on most of them: `void ca$h();` is a valid C++ source
+file according to real-world compilers.
+
+
+## Emboss Compatibility
+
+Emboss has a very long backwards-compatibility guarantee for C++: a standard
+must have been released for at least 10 years before Emboss can rely on it.
+
+| Standard | Release Date | Emboss Support Until |
+| -------- | ------------ | -------------------- |
+| C++14    | 2014-12      | 2028-01-01           |
+| C++17    | 2017-12      | 2031-01-01           |
+| C++20    | 2020-12      | 2034-11-01           |
+| C++23    | 2024-10      | 2037-01-01?          |
+
+This kind of long guarantee is common in the embedded development space, where
+compilers are often provided by vendors, and are often old versions (for
+example, at least one team using Emboss for active development was still using
+a vendor-provided C++11 compiler in late 2024).
+
+Unfortunately, this means that Emboss developers must be aware of and avoid
+dark corners that have been fixed in the latest versions of C++, or bugs that
+have been fixed in newer versions of C++ compilers.
+
+
+## C++ Memory Model: Regions
+
+Many C++ developers believe that the C++ memory model matches the simple
+"memory is a giant array" model that *processors* use: that is, that C++ (more
+or less) just exposes the machine.
+
+This is not true, and it is a significant source of danger.
+
+
+### Memory Regions and Pointer Arithmetic
+
+C++ divides memory into many, *many* tiny regions: every variable definition
+and every memory allocation gets its own region.  It then, further, defines any
+arithmetic operation whose result would point outside of that region as
+*overflow*, which is, in turn, considered to be undefined behavior:
+
+```c++
+int f() {
+  int z = 1;
+  int *zptr = &z;
+  int *zptr_minus_one = zptr - 1;  // Undefined
+  return *(zptr_minus_one + 1);    // Already in undefined land
+}
+```
+
+Pointing "inside" the region means *either* pointing to a memory location
+within the region *or* to the memory location immediately after the region
+("one past" the end of an array, where non-array objects are treated as if they
+are arrays of length 1):
+
+```c++
+int f() {
+  int z = 1;
+  int *zptr = &z;
+  int *zptr_plus_one = zptr + 1;  // OK
+  return *(zptr_plus_one - 1);    // OK
+}
+```
+
+Note that even though it is valid to create a pointer to "one past" the end of
+an object, it is still undefined behavior to *dereference* that pointer:
+
+```c++
+int f() {
+  int z = 1;
+  int *zptr = &z;
+  int *zptr_plus_one = zptr + 1;  // OK
+  return *zptr_plus_one;          // Undefined
+}
+```
+
+Comparisons between pointers into different regions are also problematic:
+
+```c++
+bool f() {
+  int s, t;
+  return &s > &t;  // Undefined (through C++20)
+                   // Unspecified result (since C++23)
+}
+```
+
+Note that equality comparisons are not quite as strict:
+
+```c++
+bool f() {
+  int s, t;
+  return &s == &t;  // OK, false
+}
+
+bool g() {
+  int s, t;
+  return &s != &t;  // OK, true
+}
+```
+
+But things can get tricky when combined with "one past the end" pointers:
+
+```c++
+bool f() {
+  int s, t;
+  return (&s) + 1 == &t;  // Unspecified result
+}
+
+bool g() {
+  int s, t;
+  return (&s) + 1 != &t;  // Unspecified result
+}
+```
+
+You also cannot serialize and deserialize pointers (at least, you cannot use
+the result):
+
+```c++
+int f() {
+  int z = 1;
+  std::stringstream s;
+  void *zptr;
+  s << &z;
+  s >> zptr;
+
+  // Undefined (until C++23?)
+  return *reinterpret_cast<int*>(zptr);
+}
+```
+
+(Note: you *may* be able to do this in C++23 and later: it's not clear to the
+author of this document.)
+
+There is an exception to this: the `printf` and `scanf` functions with the `%p`
+format specifier are specially blessed to allow it:
+
+```c++
+int f() {
+  int z = 1;
+  char buf[200];
+  void *zptr;
+  snprintf(buf, sizeof buf, "%p", &z);
+  sscanf(buf, "%p", &zptr);
+
+  // OK
+  return *reinterpret_cast<int*>(zptr);
+}
+```
+
+This blessing is not actually listed in the C++ standard: it is listed in the
+*C* standard, in a section that the C++ standard merely refers to.
+
+In the C++ standards through C++20, these rules are summarized in the section
+called "Safely-derived pointers;" e.g., C++20 (N4860), §6.7.5.4.3
+"Safely-derived pointers [basic.stc.dynamic.safety]."
+
+C++23 relaxed *some* of the rules and removed the section that summarized them:
+now, you have to find the rules scattered elsewhere in the standard.
+
+
+### The Strict Aliasing Rule
+
+In addition to being its own "island" of memory, each region gets *one type*
+for its entire lifetime, and (with specific exceptions), treating that memory
+as if it were a different type is not allowed.  Specifically, access to a
+particular object or subobject must treat the object as one of:
+
+1.  The object's type
+2.  `char`
+3.  `unsigned char`
+4.  `std::byte` (since C++17)
+5.  `std::make_signed<typeof(region)>::type`
+6.  `std::make_unsigned<typeof(region)>::type`
+7.  `T __attribute__((__may_alias__))` (Clang and GCC, maybe ICC?)
+8.  Anything (all versions of MSVC, `{g++,clang++} -fno-strict-aliasing`)
+
+The last method hints at a fact of the real world: the strict aliasing rule is
+controversial, and even compilers that claim that type punning is not allowed
+usually do not actually do anything with it.
+
+Nonetheless, at least *some* compilers take advantage of strict aliasing during
+optimization, and so in Emboss we are generally limited to the first 4 options,
+although 5 and 6 would be acceptable, and 7 and 8 can be used with guards for
+specific compilers.
+
+
+#### Unions and Strict Aliasing
+
+Many developers try to use `union` to perform type punning:
+
+```c++
+union Z { int a; short b; };
+
+short f(int a) {
+  Z z;
+  z.a = a;
+
+  return z.b;  // Undefined  (C++11 §9.2 & §9.5)
+}
+```
+
+This is undefined behavior: a `union` has exactly one "live" member at any
+given moment in the program's execution, and trying to access a non-live member
+is undefined behavior.
+
+
+#### Theoretical Issue: `std::uint8_t`
+
+Although not an issue in any real-world compiler, `std::uint8_t` does not have
+to be an alias of `unsigned char` or `char`, even on systems where `unsigned
+char` and `char` are 8 bits: `std::uint8_t` could be a so-called "extended
+integer type," which does not have the aliasing exception for `char` or
+`unsigned char`:
+
+```c++
+std::uint8_t f() {
+  int z = 1;
+
+  // In theory, undefined on some compilers.
+  return *reinterpret_cast<std::uint8_t*>(&z);
+}
+```
+
+In practice, there are no real-world compilers that do this, so it is not a
+real-world issue.
+
+
+#### Proper Bit Casting
+
+The main reason programmers violate strict aliasing is that they are trying to
+*bit cast*: to reinterpret the bit pattern of some object as some other type.
+
+There is a correct, safe way to do this, which is via `std::memcpy()`:
+
+```c++
+template <typename T, typename U>
+T bit_cast(const U &value) {
+  T result;
+  memcpy(&result, &value, sizeof result);
+  return result;
+}
+```
+
+(Note that a [real implementation][absl_bit_cast] needs more checking to be
+safe.)
+
+[absl_bit_cast]: https://github.com/abseil/abseil-cpp/blob/master/absl/base/casts.h#L152
+
+This is, unfortunately, not `constexpr`-safe until C++23.
+
+In Emboss, these kinds of bit casts are (surprisingly) rare because Emboss
+cannot rely on specifics of how a type is represented on the host machine.
+
+
+### Why the Region Model?
+
+So: why does C++ have this complicated region model and all these rules around
+pointer arithmetic?
+
+The short answer is: garbage collection!
+
+The longer answer is: a lot of reasons, but originally garbage collection!
+
+Both the C and C++ standards were written in such a way that a C++
+implementation could be conformant even with a *compacting* garbage collector.
+Things like pointer order could therefore change at any time.  Serializing and
+then deserializing a pointer "hides" that pointer from the garbage collector,
+and is therefore disallowed.  The strict aliasing rule means that the compiler
+can always figure out *what* bytes in memory actually correspond to pointers,
+and the runtime can update those pointers if it moves the region they point
+into.
+
+As of C++23, [garbage collection support was officially dropped from the
+standard][cpp23_removing_garbage_collection_support], but many of the related
+rules are still in place, so garbage collection is clearly not the *only*
+reason.
+
+[cpp23_removing_garbage_collection_support]: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2186r2.html
+
+In some cases, the rules still account for edge cases: for example, if a memory
+region is allocated very close to the upper or lower edge of the address space,
+pointer arithmetic that leaves the region could actually overflow the backing
+integer.  If two objects happen to be allocated next to each other in memory (a
+fairly common occurrence for stack objects), then a pointer to one-past one
+object may have the same numeric value as another object.  And strict aliasing,
+at least in theory, can enable certain optimizations that are otherwise
+impossible.
+
+
+## C++ Memory Model: Alignment
+
+C++ types have *alignment* requirements.  The wording in the standard ([N3337
+§ 3.11][cpp11_alignment]) is dense, but in practice it means: objects in C++
+have to exist at memory addresses that are equal to 0 modulo their alignment.
+For most modern compilers, for example, `std::int32_t` will have 4-byte (32
+bit) alignment, and so `std::int32_t` can only exist at addresses ending with
+`00` in binary (`0`, `4`, `8` or `c` in hexadecimal), like `0x4dac` or
+`0x0ee0`.  In C++, you can get the alignment of a type with `alignof`, like
+`alignof(int)`, which is guaranteed to return a positive power of 2 (1, 2, 4,
+8, etc.).
+
+[cpp11_alignment]: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf#page=89
+
+Alignment requirements are set by the C++ implementation, based on the target
+hardware.  Most implementations set their alignment requirements based on *best
+performance*, not absolute need: compilers for ARMv6 and later, for example,
+still use 32-bit alignment for `int32_t`, even though the processor itself is
+capable of doing unaligned reads: the C++ standard does not differentiate
+between "recommended" and "required" alignment.
+
+Trying to access a type through an unaligned pointer is *undefined behavior*,
+even if all aliasing, initialization, etc. rules have been followed:
+
+```c++
+int f() {
+  void *buf = operator new(sizeof(int) + 1);
+  memset(buf, 0);
+
+  // Undefined (on almost all C++ implementations)
+  int result = *reinterpret_cast<int*>(buf + 1);
+  operator delete(buf);
+  return result;
+}
+```
+
+Historically, C++ implementations did not actually enforce alignment or exploit
+the undefined behavior there, which leads developers on many platforms to think
+that unaligned access is fine.  This is not actually true, and can cause
+problems [even on processor architectures like x86][x86_alignment_bug].
+
+[x86_alignment_bug]: https://pzemtsov.github.io/2016/11/06/bug-story-alignment-on-x86.html
+
+
+### Alignment and Packed Structs
+
+"Packed struct" is a generic term for a vendor extension which allows a
+programmer to annotate a `struct` or `class` definition such that data members
+of that `struct` will be placed with no padding, even if it means that those
+members are misaligned.  For example, on GCC or Clang:
+
+```c++
+// offsetof(X, i) == 4 (on most platforms)
+struct X {
+  char c;
+  std::int32_t i;
+};
+
+// offsetof(PackedX, i) == 1
+struct __attribute__((packed)) PackedX {
+  char c;
+  std::int32_t i;
+};
+```
+
+Although packed structs are vendor extensions, they all have similar rules and
+restrictions.
+
+First, although you can access misaligned data members through a packed struct,
+the access has to be done *directly* through the packed struct: taking the
+address of an unaligned member can be dangerous:
+
+```c++
+int f() {
+  PackedX x = { 'a', 10 };
+  g(x.i);                   // OK: direct access to i
+  std::int32_t *p = &x.i;   // OK so far, but will give a warning
+
+  int y;
+  memcpy(&y, p, sizeof y);  // OK: memcpy() has no alignment requirements
+
+  return *p;                // Undefined behavior: p is misaligned
+}
+```
+
+Somewhat less well-known is that packed structs only relax their *internal*
+alignment restrictions: the packed struct *itself* still has an alignment!
+(Although on many compilers, the alignment of the packed struct is `1`.)
+
+
+## Miscellaneous Issues
+
+### Namespace Resolution
+
+Most C++ developers use `some_namespace::Name` to get at `Name` when they are
+not in `some_namespace` scope.  Most of the time this is fine, but it can cause
+errors.  The problem is that C++ starts name searches at the current scope.
+For example, take the following code:
+
+```c++
+// my_function.h
+namespace util {
+void MyFunction();
+}  // namespace util
+
+namespace my::deeply::nested::ns {
+inline void UsesMyFunction() { util::MyFunction(); }
+}  // namespace my::deeply::nested::ns
+```
+
+As written here, this will compile and work as intended.  However, it relies on
+there being no `my::util`, `my::deeply::util` or `my::deeply::nested::util`
+namespace visible at the site of the `util::MyFunction()` call.  If someone
+else writes:
+
+```c++
+// my_util.h
+
+namespace my::util {
+void SpecialFunction();
+}  // namespace my::util
+```
+
+And then yet another person tries to `#include` both files in the wrong order:
+
+```c++
+// application.cc
+
+#include "my_util.h"
+#include "my_function.h"
+```
+
+They will end up with a compilation error:
+
+```
+> g++ -c application.cc
+In file included from application.cc:4:
+my_function.h: In function ‘void my::deeply::nested::ns::UsesMyFunction()’:
+my_function.h:8:38: error: ‘MyFunction’ is not a member of ‘my::util’; did you mean ‘util::MyFunction’?
+    8 | inline void UsesMyFunction() { util::MyFunction(); }
+      |                                      ^~~~~~~~~~
+my_function.h:4:6: note: ‘util::MyFunction’ declared here
+    4 | void MyFunction();
+      |      ^~~~~~~~~~
+```
+
+Note how unhelpful G++'s error message is: "I can't find util::MyFunction(),
+did you mean util::MyFunction()?"  Clang's error is better:
+
+```
+> clang++ -c application.cc
+In file included from application.cc:4:
+./my_function.h:8:32: error: no member named 'MyFunction' in namespace 'my::util'; did you mean '::util::MyFunction'?
+inline void UsesMyFunction() { util::MyFunction(); }
+                               ^~~~~~~~~~~~~~~~
+                               ::util::MyFunction
+./my_function.h:4:6: note: '::util::MyFunction' declared here
+void MyFunction();
+     ^
+1 error generated.
+```
+
+Of course, it gets worse if `::my::util::MyFunction()` *is* defined:
+
+```
+> g++ -c application.cc
+In file included from application.cc:4:
+my_function.h: In function ‘void my::deeply::nested::ns::UsesMyFunction()’:
+my_function.h:8:48: error: too few arguments to function ‘void my::util::MyFunction(int)’
+    8 | inline void UsesMyFunction() { util::MyFunction(); }
+      |                                ~~~~~~~~~~~~~~~~^~
+In file included from application.cc:3:
+my_util.h:5:6: note: declared here
+    5 | void MyFunction(int);
+      |      ^~~~~~~~~~
+```
+
+And worst of all is if `my::util::MyFunction()` has compatible arguments: in
+that case, the wrong `MyFunction()` will be silently called!
+
+This is most important in generated code — which ends up in user-controlled
+namespaces — but as a blanket rule all Emboss code should use the `::` prefix
+for *all* top-level namespaces, even namespaces like `std`.
+
+
+### Reserved Names
+
+C++ reserves certain name patterns for language implementations, and other name
+patterns for future versions of the C++ standard.  In particular, names that
+start with `_` (in most contexts) or which contain `__` anywhere are reserved.
+
+C reserves many name patterns if you `#include` specific headers: "Each header
+declares or defines all identifiers listed in its associated subclause, and
+optionally declares or defines identifiers listed in its associated future
+library directions subclause and identifiers which are always reserved either
+for any use or for use as file scope identifiers."  (C23 §7.1.3)  For example,
+if you `#include <errno.h>` or `#include <cerrno>`: "Additional macro
+definitions, beginning with E and a digit or E and an uppercase letter, may
+also be specified by the implementation." (C23 §7.5)
+
+Although it is not part of the C or C++ standards, [POSIX reserves many names
+for its use][posix_reserved_names], including some names that are also reserved
+by C.  One particular pattern that is routinely violated in application code is
+the use of any name with the `_t` suffix: POSIX reserves all such names for
+POSIX implementors and for future revisions of POSIX.
+
+[posix_reserved_names]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html
diff --git a/doc/design.md b/doc/design.md
index 13e4b94..017fe5c 100644
--- a/doc/design.md
+++ b/doc/design.md
@@ -8,9 +8,9 @@
 The Emboss compiler is divided into separate "front end" and "back end"
 programs.  The front end parses Emboss files (`.emb` files) and produces a
 stable intermediate representation (IR), which is consumed by the back ends.
-This IR is defined in [public/ir_data.py][ir_pb2_py].
+This IR is defined in [public/ir_data.py][ir_data].
 
-[ir_pb2_py]: public/ir_data.py
+[ir_data]: public/ir_data.py
 
 The back ends read the IR and emit code to view and manipulate Emboss-defined
 data structures.  Currently, only a C++ back-end exists.
diff --git a/doc/how-to-design.md b/doc/how-to-design.md
new file mode 100644
index 0000000..04e28ea
--- /dev/null
+++ b/doc/how-to-design.md
@@ -0,0 +1,710 @@
+# Things to Think About When Designing Features for Emboss (An Incomplete List)
+
+Original Author:
+
+Ben Olmstead (aka reventlov, aka Dmitri Prime), original designer and author of
+Emboss
+
+
+# General Design Principles
+
+There are many, many books, articles, talks, classes, and exercises on good
+software design, and most general design principles apply to Emboss.  In this
+section, I will only cover the "most important" principles and those that I do
+not see highlighted in many other places.
+
+
+## Design to Real Problems, Not Hypotheticals
+
+In order to avoid "second system effect," designs that do not work in practice,
+and wasted effort, it is best to design to a specific problem — preferably a
+few instances of that problem, so that your design is more likely to solve a
+wide range of real world problems.
+
+For example, in Emboss if you wait until you have a specific data structure
+that is awkward or impossible to express, then try to find examples of other
+structures that are awkward in the same way, and then design a feature to
+handle those data structures, you are much more likely to come up with a
+solution that a) will actually be used, and b) will be used in more than one
+place.
+
+
+## Design to the Problem, Not the Solution
+
+Often, users will have a problem, think "I could solve this if I could do X,"
+and then ask for a feature for X without mentioning their original problem.  As
+a software designer, one of the first things you should do is try to figure out
+the original problem — usually by asking the user some probing questions — so
+that you can design to the problem, not to the user's solution.
+
+(Note that this is sometimes true even if you are the user: it is easy to get
+tunnel vision about a solution you came up with.  Sometimes you need to step
+back and try to find a different solution.)
+
+
+## Do Not Try to Do Everything
+
+Avoid the temptation to cover every possible use case, even if some of those
+would generally fit within the domain of your project.  A project like Emboss
+will attract extremely specific requests — requests whose solutions do not
+generalize.
+
+
+### Emboss is a "95% Solution"
+
+Instead of trying to cover every use case for every user, leave "escape
+hatches" in your design, so that users can use Emboss for the cases it covers,
+and integrate their own solutions in the places that Emboss does not cover.
+
+There will always be formats that Emboss cannot handle without becoming an
+actual programming language — even something as "basic" as compression is
+generally beyond what Emboss is meant to be capable of.
+
+
+## Be Conservative
+
+Emboss has strong backwards-compatibility guarantees: in particular, once a
+feature is "released," support for that feature is guaranteed more or less
+forever.  Because of this, new features should be narrow, even if there are
+"obvious" expansions, and even if narrowing the feature actually takes more
+code in the compiler.  You can always expand a feature later, but narrowing it
+or cutting it out would break Emboss's support guarantees.
+
+Although this principle is very standard for professional, publicly-released
+software, it may be a culture shock to developers who are used to
+"monorepo"[^mono] environments such as Google — it is not possible to just
+update all users in the real world!  Note that even many of Google's *open
+source* projects, such as Abseil, require their users to periodically update
+their code to the latest conventions, which imposes a cost on users of those
+projects.  Emboss is intended for smaller developers and embedded systems,
+which often do not have the resources for such migrations.
+
+[^mono]: In the several years that Emboss spent inside Google's monorepo it
+    underwent many large, backwards-incompatible changes that made the current
+    language significantly better.  Early incubation in a controlled
+    environment can be valuable for a new language!
+
+
+## Design for Later Expansion
+
+### Leave "Reserved Space" for Future Features
+
+Emboss uses `$` in many keyword names, but does not allow `$` to be used in
+user identifiers — this lets Emboss add `$` keywords without worrying about
+colliding with identifiers in existing code.  (This is in direct contrast to
+most programming languages, where introducing new keywords often breaks
+existing code.)
+
+As another example, Emboss disallows identifiers that collide with keywords in
+many programming languages — this gives room for Emboss to add back ends for
+those programming languages later, without having to figure out a convention
+for mangling identifiers that collide.  As a real-world counterexample,
+Protocol Buffers had to figure out a convention for handling field names that
+collide with C++ identifiers such as `class` — and `protoc` still generates
+broken C++ code if you have two fields named `class` and `class_` in the same
+`message`.
+
+
+### Leave "Extension Points"
+
+An "extension point" is a place where someone should be able to hook into the
+system without changing the system.  This can be an API, a "hook," a defined
+data format, or something else entirely, but the defining factor is that it is
+a way to add new features or alter behavior without changing the existing
+software.
+
+In practice, many extension points won't "just work" until there are at least a
+few things using them, due to bugs or unexpected coupling, but in principle
+they should not require any modification.
+
+One extension point in the Emboss compiler is the full separation between front
+and back ends, so that future back ends (such as Rust, Protocol Buffers, PDF
+documentation, etc.) can be added without changing the overall design or
+(theoretically) any of the existing compiler.[^ext]
+
+[^ext]: This is not unique or original to Emboss: separate front and back ends
+    are totally standard in modern compiler design.
+
+In the physical world, an electrical outlet or a network port is an extension
+point — there is nothing there right now, but there is a defined place for
+something to be added later.
+
+
+### Leave "Lines of Cleavage"
+
+A "line of cleavage" is similar to an extension point, except that instead of
+being a ready-to-go place to add something new, it's a place where the major
+work was done, but there are still some pieces that need to be fixed up.
+
+A line of cleavage in the Emboss compiler is the use of a special `.emb` file
+(`prelude.emb`) to define "built-in" types, with the aim of eventually allowing
+end users to define their own types at the same level.  This feature still has
+open design decisions, such as:
+
+*   How will users define their type for the back end(s)?
+*   How will users define the range of an integer type for the expression
+    system?
+
+But these are relatively minor compared to the larger question of "how can
+Emboss allow end users to define their own basic types?"
+
+In software, lines of cleavage are usually invisible to end users, and can be
+difficult to see even for developers working on the code.
+
+In the physical world, an example of this is putting empty conduit into walls
+or ceilings: that way, new electrical or communication wires or pneumatic tubes
+can be pulled through the conduit and attached to new outlets, without having
+to open up *all* the walls.
+
+
+## Consider Known Potential Features
+
+Every complex software system has a cloud of potential features around it:
+features which, for one reason or another, have not been implemented yet, but
+which some stakeholder(s) want.  These features usually exist at every stage
+from "idle thought in a developer's mind" to "partially implemented, but not
+finished," and the likelihoods of each one to become a finished feature cover
+an equally wide range.
+
+When designing a new feature there are very good reasons to think about these
+potential features:
+
+First, you should ensure that your new feature does not make another
+highly-desirable feature impossible.  In Emboss, for example, if your new
+feature made it impossible to support a string type, that would be a very good
+reason to redesign your feature (or abandon it, if it is fundamentally
+incompatible).
+
+Second, sometimes you can tweak your design so that a potential feature becomes
+obsolete: fundamentally, every feature request exists to solve a problem, and
+often it is not the only way to solve that problem.  If you can solve it in a
+different way, you can make users happy and avoid some future work.  (Though be
+careful: it can be difficult to infer the full scope of a user's problem(s)
+from a feature request.)
+
+Third, thinking about specific potential features can help narrow the amount of
+"future design space" that you need to consider, which makes it easier to put
+extension points and lines of cleavage in your design in places where they will
+actually be used.
+
+
+# General Language Design Principles
+
+In contrast to general software design principles, there are far fewer sources
+on good *language* design.  I speculate that this is because there are far
+fewer language designers than software designers.  (There are tens of millions
+of software developers, but only tens of thousands of programming, markup, and
+data definition languages — and of those, maybe two thousand or so are
+"serious" languages with significant real-world use.)
+
+Luckily, there are many publicly available and documented languages to learn
+from directly.
+
+Language design can be very roughly divided into syntactic and semantic
+concerns: syntax is how the language *looks* (what symbols and keywords are
+used, and in what order), while semantics cover how the language *works* (what
+actually happens).  It might seem like semantics are more important, but syntax
+has a huge effect on how easy it is to understand existing code and to write
+correct code, which are both incredibly important in real-world use.
+
+In this section, I will try to outline language design principles that I have
+found or developed, particularly when they are useful for Emboss.
+
+
+## Be Mindful of the Power/Analysis Tradeoff
+
+[Turing-complete languages cannot be fully
+analyzed](https://en.wikipedia.org/wiki/Halting_problem).  This is one of the
+reasons that languages like HTML and CSS are not programming languages: the
+more expressive a language is, the more difficult it is to analyze.
+
+The `.emb` format is intended to be more on the declarative side, so that
+definitions can be analyzed and transformed as necessary.
+
+
+## Look at Other Languages
+
+Although Emboss is a data definition language (DDL), not a programming
+language, many lessons and principles from programming language design can be
+applied, as well as lessons from other DDLs, and sometimes even interface
+definition languages (IDLs), as well as markup and query languages.
+
+In particular, for Emboss it is often worth looking at:
+
+*   Popular programming languages: C, C++, Rust, JavaScript, TypeScript, C#,
+    Java, Go, Python 3, Swift, Objective C, Lua.  "Systems" programming
+    languages such as C, C++, and Rust are usually the most relevant of these,
+    but it is useful to survey all the popular languages because many Emboss
+    users will be familiar with them.  Note that Lua is used for Wireshark
+    packet definitions.
+
+*   Selected "interesting" programming languages: Wuffs, Haskell, Ocaml, Agda,
+    Coq.  These have some lessons for Emboss, especially its expression system
+    — in particular, they're all much more principled than "standard"
+    programming languages about how they handle types and values.  There are
+    many other programming languages that have interesting ideas (FORTH,
+    Prolog, D, Perl, Logo, Scratch, APL, so-called "esoteric" programming
+    languages), but they usually are not relevant to Emboss.
+
+*   DDLs: Kaitai Struct, Protocol Buffers, Cap'n Proto, SQL-DDL.  Kaitai Struct
+    is the closest of these to solving the same problem as Emboss (though it
+    has some fundamentally different design decisions which make it far worse
+    for embedded systems), but all have some lessons.  Some higher-level schema
+    languages like DTD, XML Schema, or JSON Schema tend to be less relevant to
+    Emboss.  Note that there are a number of DDLs that are also IDLs: in actual
+    use, some of them (Protocol Buffers) are used more often for their DDL
+    features, while others (XPIDL, COM) are used more for their IDL features.
+
+
+## Learn Academic Theory
+
+Many (most?) languages are designed by people who have minimal knowledge of the
+academic theories of how programming languages work — for Emboss, Category
+Theory is particularly useful, and the computer science of parsers (especially
+LR(1) parsers) is useful for tweaking the parser generator or adding new
+syntax.
+
+This is a case where a little bit of learning goes a long way: you do not need
+to learn a *lot* about parsers or Category Theory to benefit from them.
+
+
+## Try to Acquire Practical Knowledge
+
+Many of the academic topics related to programming language design have
+corresponding industrial knowledge, and there are practical concerns that have
+very little to do with academic theory.
+
+The Emboss compiler is (loosely) based on the design of LLVM, with a series of
+transformation passes that operate somewhat independently, and independent back
+end code generators.[^designoops]
+
+[^designoops]: After many years of experience with this, I think that this is
+    not quite the right design for Emboss, and I would make two major changes:
+    first (and simplest), I would divide the current "front end" into a true
+    front end that only handled syntax and some types of syntax sugar, and a
+    "middle end" that handled all of the symbol resolution, bounds analysis,
+    constraint checking, etc.  Second, I would use a "compute-on-demand" (lazy
+    evaluation) approach in the middle end, which would allow certain
+    operations to be decoupled.  The LLVM design is more suited for independent
+    optimization passes, not for the kind of gradual annotation process in the
+    Emboss middle end.
+
+As another example, understanding how (and how well) Clang, GCC, and MSVC can
+optimize C++ code is crucial to generating high-performance code from Emboss
+(and Emboss leans very heavily on the C++ compiler to optimize its output).
+
+Some bits of practical knowledge are tiny little bits of almost-trivia.  For
+example, if you have C or C++ code in a (text) template, and you use `$` to
+indicate substitution variables (as in `$var` or `$var$`), then most editors
+and code formatters will treat your substitution variables as normal
+identifiers.  This is because almost every C and C++ compiler allows you to use
+`$` in identifiers, even though there has never been a C or C++ standard that
+allows those names, and it is rarely noted in any compiler, editor, or
+formatter's documentation.
+
+
+## Use Existing Syntax
+
+Emboss pulls many conventions from programming, data definition, and markup
+languages.  In general, if there is a feature in Emboss that works in a way
+that is the same as in other languages, it is best to pull syntax from
+elsewhere — ideally, pull in the most common syntax.  Many examples of this in
+Emboss are so common you might not even think about them:
+
+*   Arithmetic operators (`+`, `-`, `*`)
+*   Operator precedence (`*` binds more tightly than `+` and `-`, but also: see
+    the next section)
+
+Other examples are most specific, with no universal convention:
+
+*   `: Type` syntax for type annotation (TypeScript, Python, Ocaml, Rust, ...)
+
+This is *especially* important for Emboss, because most people reading or
+writing Emboss code will not want to spend much time becoming an "Emboss
+expert" — where someone might be willing to spend days or weeks to learn how to
+write Rust code, they are more likely to spend hours or minutes learning to
+write Emboss.
+
+
+## Avoid Existing Syntax
+
+However, there are three main reasons to avoid using existing syntax:
+
+*   The "standard" syntax is error prone.  One example of this is operator
+    precedence in most programming languages: errors related to not knowing the
+    relative precedence of `&&` and `||` are so common that most compilers have
+    an option to warn if they are mixed without parentheses.  Emboss handles
+    this — and a few other error-prone constructs — by having a *partial
+    ordering* for precedence instead of the standard total ordering, and making
+    it a syntax error to mix operators such as `&&` and `||` that have
+    incomparable (neither equal, less than, nor greater than) precedence.  As
+    far as I can tell, this is a totally new innovation in Emboss: there is no
+    precedent (no pun intended) whatsoever for partial precedence order.
+
+    When avoiding syntax in this way, it is ideal to make the standard syntax
+    into a syntax error (so that no one can use it accidentally) and to add an
+    error message to the compiler that suggests the correct syntax.
+
+*   The existing syntax is not used consistently: if multiple programming
+    languages use the same syntax for slightly different semantics, it is
+    usually worth avoiding the syntax.  For example, `/` has quite a few
+    different semantics — in many languages, it is a type-parameterized
+    division, where the numeric result depends on the (static or dynamic) types
+    of its operands, and across languages, the "integer division" flavor is not
+    consistent — in most programming languages it is *truncating division* (`-7
+    / 3 == -2`), but in some programming languages it is *flooring division*
+    (`-7 / 3 == -3`).
+
+*   The semantics do not match: if an Emboss feature is *almost*, but *not
+    quite* equivalent to a feature in other languages, it is best to avoid
+    making the Emboss feature look like the other feature.
+
+
+## Poll Users/Programmers
+
+When designing a new feature, try to come up with several alternatives and poll
+Emboss users (or sometimes non-Emboss-using programmers) as to which one they
+prefer.
+
+For syntax, one especially powerful technique is to show an example of the
+proposed syntax to people who have never seen it, and ask "what do you think
+this means?" without any hinting or prompting.  This is the "gold standard" way
+of finding out whether your syntax is clear or not.
+
+
+## Avoid Error-Prone Constructs
+
+Computing now has roughly seventy years of experience with artificial languages
+(in programming, markup, data definition, query, etc. flavors), and we have
+learned a lot about what kinds of constructs are error-prone for humans to use.
+Avoid these, where possible!  Some examples include:
+
+*   Large semantic differences should not have small, easily-overlooked
+    syntactic differences.  For example, allowing single- and double-character
+    operators (`=` and `==`, `|` and `||`, etc.) in the same contexts: a
+    classic C-family programming error is to use `=` in a condition instead of
+    `==`.  Many modern languages either force `=` to be used only in "statement
+    context" (and some, like C#, also ban side-effectless statements such as `x
+    == y;`) or use a different operator like `:=` for assignment.  (Or both, as
+    in Python, which allows `:=` but not `=` for "expression assignment.")
+
+*   Syntax should have *consistent* semantic meaning.  For example, in
+    JavaScript these two snippets mean the same thing:
+
+    ```js
+    return f() + 10;
+    ```
+
+    ```js
+    return f() +
+              10;
+    ```
+
+    but this one is different (it returns `undefined`, thanks to JavaScript's
+    automatic `;` insertion):
+
+    ```js
+    return
+        f() + 10;
+    ```
+
+    A small difference in the placement of the line break leads to totally
+    different semantics!
+
+    C++ has a number of places where identical syntax can have wildly different
+    semantics, especially (ab)use of operator overloads and [the most vexing
+    parse](https://en.wikipedia.org/wiki/Most_vexing_parse).
+
+*   Hoare calls "null" his "billion-dollar mistake," and the way that null
+    pointers are handled in most programming languages, especially C and C++,
+    is particularly error-prone.  (But note that it isn't really "null" itself
+    that is problematic — it's that there is no way to mark a pointer as "not
+    null," and that doing anything with a null pointer leads to undefined
+    behavior.  However, some popular language features, such as the `?.`
+    operator found in several programming languages and the `std::optional<>`
+    type in C++, show that there is some utility to nullable types, as long as
+    there is language support for enforcing null checks and/or allowing null to
+    propagate in the same way that NaN can.)
+
+*   Edge cases, such as integer overflow, are difficult for humans to reason
+    about.  In systems programming languages like C and C++, this leads to a
+    significant percentage of security flaws.  (C and C++ compilers use the
+    "integer overflow is undefined" rule *extensively* in optimization, so
+    there are pragmatic trade-offs in general.  Emboss is used in smaller
+    contexts with tighter safety guarantees.)
+
+
+# Emboss-Specific Considerations
+
+Emboss sits in a section of design space that has very few alternatives, and as
+a result there are things to think about when designing Emboss features that do
+not apply to many other languages.
+
+Also, because Emboss already exists, there are a number of systems within
+Emboss-the-language that may interact with new features.
+
+And finally, if you want your feature to become implemented, it is necessary to
+consider how difficult it would be to implement new features in `embossc`.
+
+
+## Survey Data Formats
+
+Maybe the least fun (at least for me[^unfun]) part of designing Emboss features
+is reading through data sheets, programming manuals, RFCs, and user guides to
+understand the data formats used in the real world, so that any new feature can
+handle a reasonable subset of those formats.  Some sources to consider:
+
+*   Data sheets and programming manuals for:
+    *   complex sensors, such as LiDAR
+    *   GPS receivers
+    *   servos
+    *   LED panels and segmented displays
+    *   clock hardware
+    *   ADCs and DACs
+    *   camera sensors
+    *   power control devices
+    *   simple sensors such as barometers, hygrometers, current sensors,
+        voltage sensors, light sensors, etc. (though many very simple sensors
+        use analog outputs or very, very simple digital outputs that do not
+        have a "protocol" as such)
+*   RFCs for low-level protocols such as Ethernet, IP, ICMP, UDP, TCP, and ARP
+
+<!-- TODO: assemble a list of links to actual examples -->
+
+[^unfun]: One of my original motivations for creating Emboss is that I find
+    reading data sheets and implementing code to read/write the data formats
+    therein to be extremely tedious.
+
+
+## Structure Layout System
+
+The "heart" of Emboss is what may be called the "structure layout system:" the
+engine that determines which bits to read and write in order to produce or
+commit the values of fields.  When designing, consider:
+
+*   Does this feature require reaching "outside" of a scope?  For example,
+    referencing a sibling field from within a field's scope is currently
+    impossible, because each field has its own scope.  Allowing `[requires:
+    this == sibling]` means expanding that scope.
+
+*   Does this feature require information that is not (currently) available to
+    the layout engine, or not available at the right place or time?  For
+    example, if you are designing a feature to allow field sizes to be `$auto`,
+    how does that interact with structures that are variable size?
+
+*   Does this feature require information that is potentially circular, or
+    would it interact with another potential feature to require circular
+    information, and is there a way to resolve that?  For example: if you are
+    designing a feature to allow field sizes to be `$auto`, inferring their
+    size from their type, how will that interact with the potential feature to
+    allow `struct`s that grow to the size they are given?
+
+
+## Expression System
+
+Although most expressions in Emboss definitions are simple (such as `x*4` or
+even just `0`), the expression system in Emboss tracks a lot of information,
+such as:
+
+*   What is the type of every subexpression (e.g., integer, specific
+    enumeration, opaque, etc.)?
+*   For integer and boolean expressions, does the expression evaluate to fixed
+    (constant) value?
+*   For integer expressions, what are the upper and lower bounds of the
+    expression?  (Used for determining the correct integer types to use in
+    generated code.)
+*   For integer expressions, is the value guaranteed to be equal to some fixed
+    value modulo some constant?  (Used for generating faster code for aligned
+    memory access.)
+
+When designing a feature, consider:
+
+*   Will any new types be `opaque` to the expression system, or will it be
+    possible to perform operations on them?  If they are `opaque` for now, will
+    they stay that way, or will it be possible to manipulate them in the
+    future?  For example, adding a string type in Emboss might start as
+    `opaque`, but allow operations like "value at index" or "substring" in the
+    future.
+*   When adding new operations, how will they interact with the bounds and
+    alignment tracking?  For example: truncating division often breaks
+    alignment tracking, whereas flooring division does not.
+*   Will this feature invalidate existing code?  Anything that causes the
+    inferred integer bounds of existing code to expand can break existing code.
+
+Note that the entire point of Emboss is to provide a bridge between physical
+data layout (as defined in the structure layout system) and abstract values
+with no specific representation (as exposed through the expression system).
+
+
+## Parsing
+
+Any new syntax has to be added to the parser.  Aside from the language design
+considerations for new syntax (see the ["General Language Design Principles"
+section](#general-language-design-principles)), there are a few levels of
+concern for the actual implementation:
+
+*   Is it computationally feasible to parse this syntax in an intuitive,
+    unambiguous way?
+*   Is it humanly feasible to express this syntax as an LR(1) grammar that can
+    be parsed by Emboss's shift-reduce parser engine?
+*   Is it feasible to parse this syntax using a different parsing engine type
+    (Earley, recursive descent, TDOP, parser combinator, etc.)?
+
+The first consideration is more of a general language design consideration: if
+your language design says "users will be able to specify their program in
+English," that is not really feasible (or unambiguous).  (Not that it hasn't
+been tried, many times.)
+
+The second consideration — can you add this syntax to `embossc`? — is the most
+practical and important consideration for Emboss.  LR(1) grammars are pretty
+restrictive (though shift-reduce parsers have advantages — there are reasons
+Emboss is using one), and even when it is *possible* to express a particular
+syntactic construct in LR(1)[^zimm], it may be difficult for most programmers to
+actually do so.  As a practical matter, I recommend trying to actually add your
+syntax to `module_ir.py`.
+
+[^zimm]: I (Ben Olmstead) think it would be awesome to implement [[Zimmerman,
+    2022](https://arxiv.org/abs/2209.08383)] plus a few extensions of my own
+    devising in Emboss's shift-reduce engine, which would make the grammar
+    design space significantly larger.  I would also separate the parser
+    generator engine into its own project.
+
+The third consideration is more future-focused and abstract: does this syntax
+lock Emboss into using a shift-reduce parser in the future?  Ideally, no.
+Luckily(?), LR(1) grammars are one of the more restrictive types of grammars in
+common use, so it is likely that anything that can be handled by the current
+parser can be handled by many other types of parsers.
+
+
+## Generated Code
+
+Right now, there is only the generated C++ code, but there should be other back
+ends in the future.  Some new features are pure syntax sugar (e.g., `$next` or
+`a < b < c`) that are replaced in the IR long before it reaches the back end
+(e.g., with the offset+length of the syntactically-previous field, or the IR
+equivalent of `a < b && b < c`), while others require extensive changes to how
+code is generated.
+
+*   What information will the back end need in order to generate working code?
+*   Does this feature require embedded-unfriendly generated code?  (E.g.,
+    memory allocation, I/O.)
+*   Can the existing C++ back end, which just walks the IR tree in a single
+    pass while building up strings which are combined into a `.h`, handle this
+    feature in its current design?
+*   How will this feature interact with various generated templates?
+*   Can/should this feature be, itself, templated?
+
+
+## C++ Runtime Library
+
+The runtime library will be included with every program that touches Emboss, so
+it is important to make it efficient.  When adding features, consider:
+
+*   Can the feature be added in such a way that it does not cost anything for
+    programs that do not use the feature?  A standalone C++ template will not
+    be included in a program unless the program instantiates the template, but
+    if the new code is used from somewhere in an existing function, it may be
+    included in programs that do not use it directly.
+
+*   Can the feature be added without allocating any heap memory?  Can it be
+    added with O(1) stack memory use?  Both of these are important for some
+    embedded systems, such as OS-less microcontroller and hard-real-time
+    environments.  Some features may intrinsically require memory allocation,
+    in which case it is best if they can be separated: for example, Emboss
+    structure-to-string conversion requires allocation, and even `#include`'ing
+    the appropriate headers can be too much for some environments, even if the
+    serialization code is never included in the final binary.
+
+*   How much can you rely on the C++ compiler to optimize things?  If you have
+    to implement your own optimizations, that will cost more development time
+    and add more complexity to the standard library.
+
+
+## Compiler Complexity
+
+The Emboss compiler is already quite complex, and has many subsystems that
+interact.  It is already quite difficult to reason about some interactions.
+
+*   Can the feature be added at an "edge" of the compiler?  For example, if you
+    can implement your feature as syntax sugar that converts the new feature to
+    existing IR early in the compilation process, it is much easier to verify
+    that it will not cause problematic interactions.  Similarly, if you can
+    implement your feature entirely in the back end or in the runtime library,
+    you do not need to worry about interactions inside the front end.
+
+*   If a feature cannot be added at an edge, how can you design it to minimize
+    the complexity?  (Ideally, you could even unify existing systems in such a
+    way that the overall complexity of the compiler is lower at the end.)
+
+
+## Future Back Ends
+
+It is important to have some idea of how any feature would be implemented
+against future back ends.
+
+
+### Programming Language (Rust/Python/Java/Go/C#/Lua/etc) Back Ends
+
+Some features may be difficult to implement in other languages.  For example,
+Python does not have a native `switch` statement, so any `switch`-like feature
+in Emboss may be awkward to implement — but this does not necessarily mean that
+Emboss should not have a `switch`.
+
+As a rule of thumb, languages can be grouped into tiers:
+
+1.  "Systems"/embedded-friendly languages: C++, Rust, C.  Top support.
+2.  Languages used for parsing/analyzing raw sensor dumps: C#, Java, Go,
+    Python, etc.  Should have good support, but not gate any features.
+3.  Languages that are rarely used to touch binary data: JavaScript,
+    TypeScript, etc.  Can be mostly ignored.
+4.  Dead and obscure languages: Perl, COBOL, APL, INTERCAL, etc.  Can be
+    ignored entirely.
+
+(It may be difficult to classify some languages, such as FORTRAN, which is
+still hanging around in 2024.)
+
+Remember that other back ends may have different requirements and guarantees
+than the C++ back end: for example, it would be unreasonable for a Java back
+end to promise "no dynamic memory allocation."
+
+
+### Other Data Format (Protobuf/JSON/etc) Back Ends
+
+These back ends would translate binary structures into alternate
+representations that are easier for some tools to use: for example, Google has
+many, many tools for processing Protocol Buffers, and JSON is popular in the
+open-source world.
+
+Most other formats have limitations that may make some kinds of Emboss
+constructs difficult or impossible to correctly reproduce: for example, Emboss
+already supports "infinitely nested" `struct` types, like:
+
+```
+struct Foo:
+    0 [+10]  Foo  child_foo
+```
+
+Formats like Protobuf or JSON, which do not have any way of representing loops
+in their data graph, cannot handle this.
+
+Until the most recent versions of Protobuf, mismatches between Protobuf `enum`
+and Emboss `enum` made it functionally impossible to map any Emboss `enum`
+types onto Protobuf `enum` types: Emboss `enum` types are open (allow any
+value, even ones that are not listed in the `enum`), where all Protobuf `enum`
+types were closed (only allowed known values).  (The most recent Protobuf
+versions, Proto3 and Editions, allow you to have open `enum` types.)
+
+Generally, it is not worth blocking an Emboss feature because of these kinds of
+mismatches, but it is worth thinking about how to avoid them, if possible.
+
+
+### Documentation (PDF/Markdown/etc) Back Ends
+
+These back ends would translate `.emb` files to a form of human-readable
+documentation, intended for publication on a web site, in an RFC, or as part of
+a PDF datasheet.  This type of back end is the motivation for having both `--`
+documentation blocks and `#` comments in Emboss.
+
+Since the output from these back ends would be intended for human consumption,
+for the most part you would only need to ensure that your feature can be
+understood by humans.
diff --git a/doc/how-to-implement.md b/doc/how-to-implement.md
new file mode 100644
index 0000000..452d2d1
--- /dev/null
+++ b/doc/how-to-implement.md
@@ -0,0 +1,203 @@
+# How to Implement Changes to Emboss
+
+<!-- TODO(bolms): write and link to guides on the `embossc` design -->
+
+## Getting the Code
+
+The master Emboss repository lives at https://github.com/google/emboss — you
+can `git clone` that repository directly, or make [a fork on
+GitHub](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/about-forks)
+and then `git clone` your fork.
+
+
+## Prerequisites
+
+In order to run Emboss, you will need [Python](https://www.python.org/).
+Emboss supports all versions of Python that are [still supported by the
+(C)Python codevelopers](https://devguide.python.org/versions/), but versions
+older than that generally will not work.
+
+The Emboss tests run under [Bazel](https://bazel.build/).  In order to run the
+tests, you will need to [install Bazel](https://bazel.build/start) on your
+system.
+
+
+## Running Tests
+
+Emboss has a reasonably extensive test suite.  In order to run the test suite,
+`cd` into the top `emboss` directory, and run:
+
+```sh
+bazel test ...
+```
+
+Bazel will download the necessary prerequisites, compile the (C++) code, and
+run all the tests.  Tests will take a moment to compile and run; Bazel will
+show running status, like this:
+
+```
+Starting local Bazel server and connecting to it...
+[502 / 782] 22 actions, 21 running
+    Compiling runtime/cpp/test/emboss_memory_util_test.cc; 10s linux-sandbox
+    Compiling runtime/cpp/test/emboss_memory_util_test.cc; 10s linux-sandbox
+    Creating runfiles tree bazel-out/k8-fastbuild/bin/compiler/front_end/emboss_front_end.runfiles; 2s local
+    Creating runfiles tree bazel-out/k8-fastbuild/bin/compiler/front_end/synthetics_test.runfiles; 1s local
+    Creating runfiles tree bazel-out/k8-fastbuild/bin/compiler/front_end/make_parser_test.runfiles; 1s local
+    Creating runfiles tree bazel-out/k8-fastbuild/bin/compiler/back_end/cpp/header_generator_test.runfiles; 1s local
+    Compiling absl/strings/str_join.h; 0s linux-sandbox
+    Creating runfiles tree bazel-out/k8-fastbuild/bin/compiler/front_end/generate_cached_parser.runfiles; 0s local ...
+```
+
+You may see a few `WARNING` messages; these are generally harmless.
+
+Once Bazel finishes running tests, you should see a list of all tests and their
+status (all should be `PASSED` if you just cloned the main Emboss repo):
+
+```
+Starting local Bazel server and connecting to it...
+INFO: Analyzed 226 targets (98 packages loaded, 4080 targets configured).
+INFO: Found 116 targets and 110 test targets...
+INFO: Elapsed time: 65.577s, Critical Path: 22.22s
+INFO: 862 processes: 372 internal, 490 linux-sandbox.
+INFO: Build completed successfully, 862 total actions
+//compiler/back_end/cpp:alignments_test                                  PASSED in 0.2s
+//compiler/back_end/cpp:alignments_test_no_opts                          PASSED in 0.1s
+//compiler/back_end/cpp:anonymous_bits_test                              PASSED in 0.2s
+//compiler/back_end/cpp:anonymous_bits_test_no_opts                      PASSED in 0.1s
+[... many more tests ...]
+//runtime/cpp/test:emboss_prelude_test                                   PASSED in 0.2s
+//runtime/cpp/test:emboss_prelude_test_no_opts                           PASSED in 0.2s
+//runtime/cpp/test:emboss_text_util_test                                 PASSED in 0.2s
+//runtime/cpp/test:emboss_text_util_test_no_opts                         PASSED in 0.2s
+
+Executed 110 out of 110 tests: 110 tests pass.
+```
+
+If a test fails, you will see lines at the end like:
+
+```
+//compiler/back_end/cpp:alignments_test                                  FAILED in 0.0s
+  /usr/local/home/bolms/.cache/bazel/_bazel_bolms/444a471ee8e028e0535394d088883276/execroot/_main/bazel-out/k8-fastbuild/testlogs/compiler/back_end/cpp/alignments_test/test.log
+
+Executed 110 out of 110 tests: 109 tests pass and 1 fails locally.
+```
+
+You can read the `test.log` file to find out where the failure occurred.
+
+Note that each C++ test actually runs multiple times with different Emboss
+`#define` options, so a single failure may cause multiple Bazel tests to fail:
+
+```
+//compiler/back_end/cpp:alignments_test                                  FAILED in 0.0s
+  /usr/local/home/bolms/.cache/bazel/_bazel_bolms/1c6e4694f903a02feef32c92ec3f1cae/execroot/_main/bazel-out/k8-fastbuild/testlogs/compiler/back_end/cpp/alignments_test/test.log
+//compiler/back_end/cpp:alignments_test_no_checks                        FAILED in 0.0s
+  /usr/local/home/bolms/.cache/bazel/_bazel_bolms/1c6e4694f903a02feef32c92ec3f1cae/execroot/_main/bazel-out/k8-fastbuild/testlogs/compiler/back_end/cpp/alignments_test_no_checks/test.log
+//compiler/back_end/cpp:alignments_test_no_checks_no_opts                FAILED in 0.0s
+  /usr/local/home/bolms/.cache/bazel/_bazel_bolms/1c6e4694f903a02feef32c92ec3f1cae/execroot/_main/bazel-out/k8-fastbuild/testlogs/compiler/back_end/cpp/alignments_test_no_checks_no_opts/test.log
+//compiler/back_end/cpp:alignments_test_no_opts                          FAILED in 0.0s
+  /usr/local/home/bolms/.cache/bazel/_bazel_bolms/1c6e4694f903a02feef32c92ec3f1cae/execroot/_main/bazel-out/k8-fastbuild/testlogs/compiler/back_end/cpp/alignments_test_no_opts/test.log
+
+Executed 168 out of 168 tests: 164 tests pass and 4 fail locally.
+```
+
+(The Emboss repository goes one step further and runs each of *those* tests
+under multiple compilers and optimization options.)
+
+If you are working on fixing a failure in one particular test, you can tell
+Bazel to run just that test by specifying the name of the test on the command
+line:
+
+```
+bazel test //compiler/back_end/cpp:alignments_test
+```
+
+This can be quicker than re-running the entire test suite.
+
+
+### `docs_are_up_to_date_test`
+
+If you are making changes to the Emboss grammar, you can ignore failures in
+`docs_are_up_to_date_test` until you have your updated grammar finalized: that
+test ensures that certain generated documentation files are up to date when
+code reaches the main repository.  See [Checked-In Generated
+Code](#checked-in-generated-code), below.
+
+
+## Implementing a Feature
+
+The the Emboss compiler is under [`compiler/`](../compiler/), with
+[`front_end/`](../compiler/front_end/), [`back_end/`](../compiler/front_end/),
+and [`util/`](../compiler/util/) directories for the front end, back end, and
+shared utilities, respectively.
+
+The C++ runtime library is under [`runtime/cpp/`](../runtime/cpp).
+
+
+### Coding Style
+
+For Python, Emboss uses the default style of
+the [Black](https://black.readthedocs.io/en/stable/) code formatter.[^genfile]
+
+[^genfile]: There is one, very large, generated `.py` file checked into the
+    Emboss repository that is intentionally excluded from code formatting —
+    both because it can hang the formatter and because the formatted version
+    takes noticeably longer for CPython to load.
+
+For C++, Emboss uses the `--style=Google` preset of
+[ClangFormat](https://clang.llvm.org/docs/ClangFormat.html).
+
+
+## Writing Tests
+
+Most code changes require tests: bug fixes should have at least one test that
+fails before the bug fix and passes after the fix, and new features should have
+many tests that cover all aspects of how the feature might be used.
+
+
+### Python
+
+The Emboss Python tests use the Python
+[`unittest`](https://docs.python.org/3/library/unittest.html) module.  Most
+[tests of the Emboss front end](../compiler/front_end/) are structured as:
+
+1.  Run a small `.emb` file through the front end, stopping immediately before
+    the step under test, and hold the result IR (intermediate representation).
+2.  Run the step under test on that IR, making sure that there are either no
+    errors, or that the errors are expected.
+3.  For the "no errors" tests, check various properties of the resulting IR to
+    ensure that the step under test did what it was supposed to.
+
+
+### C++
+
+The Emboss C++ tests use [the GoogleTest
+framework](https://google.github.io/googletest/).
+
+[Pure runtime tests](../runtime/cpp/test) `#include` the C++ runtime library
+headers and manually instantiate them, then test various properties.
+
+[Generated code tests](../compiler/back_end/cpp/testcode/), which incidentally
+test the runtime library as well, work by using a header generated from a [test
+`.emb`](../testdata/) and interacting with the generated Emboss code the way
+that a user might do so.
+
+
+## Writing Documentation
+
+If you are adding a feature to Emboss, make sure to update [the
+documentation](../doc/).  In particular, the [language
+reference](../doc/language-reference.md) and the [C++ code
+reference](cpp-reference.md) are very likely to need to be updated.
+
+
+## Checked-In Generated Code
+
+There are several checked-in generated files in the Emboss source repository.
+As a general rule, this is not a best practice, but it is necessary in order to
+achieve the "zero installation" use of the Emboss compiler, where an end user
+can simply `git clone` the repository and run the `embossc` executable directly
+— even if the cloned repository lives on a read-only filesystem.
+
+In order to minimize the chances of any of those files becoming stale, each one
+has a unit test that checks that the file in the Emboss directory matches what
+its generator would currently generate.
diff --git a/doc/index.md b/doc/index.md
index 6c383e8..7cfb5d6 100644
--- a/doc/index.md
+++ b/doc/index.md
@@ -16,3 +16,8 @@
 the [Emboss Text Format Reference](text-format.md).
 
 There is a tentative [roadmap of future development](roadmap.md).
+
+If you are interested in contributing to Emboss, please read [Contributing to
+Emboss](contributing.md), and you may wish to read [How to Design Features for
+Emboss](how-to-design.md) and [How to Implement Changes to
+Emboss](how-to-implement.md).
diff --git a/emboss-format b/emboss-format
new file mode 100755
index 0000000..a0dd827
--- /dev/null
+++ b/emboss-format
@@ -0,0 +1,25 @@
+#!/usr/bin/env python3
+
+# Copyright 2025 Benjamin Olmstead
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Standalone driver program for the Emboss formatter."""
+
+import sys
+
+from compiler.front_end import format
+
+
+if __name__ == "__main__":
+    sys.exit(format.main(sys.argv))
diff --git a/embossc b/embossc
index 7bc0227..90775ef 100755
--- a/embossc
+++ b/embossc
@@ -22,83 +22,90 @@
 
 
 def _parse_args(argv):
-  parser = argparse.ArgumentParser(description="Emboss compiler")
-  parser.add_argument("--color-output",
-                      default="if_tty",
-                      choices=["always", "never", "if_tty", "auto"],
-                      help="Print error messages using color.  'auto' is a "
-                           "synonym for 'if_tty'.")
-  parser.add_argument("--import-dir", "-I",
-                      dest="import_dirs",
-                      action="append",
-                      default=["."],
-                      help="A directory to use when searching for imported "
-                           "embs.  If no import-dirs are specified, the "
-                           "current directory will be used.")
-  parser.add_argument("--generate",
-                      nargs=1,
-                      choices=["cc"],
-                      default="cc",
-                      help="Which back end to use.  Currently only C++ is "
-                           "supported.")
-  parser.add_argument("--output-path",
-                      nargs=1,
-                      default=".",
-                      help="""Prefix path to use for the generated output file.
-                              Defaults to '.'""")
-  parser.add_argument("--output-file",
-                      nargs=1,
-                      help="""File name to be used for the generated output
-                              file. Defaults to input_file suffixed by '.h'""")
-  parser.add_argument("--cc-enum-traits",
-                      action=argparse.BooleanOptionalAction,
-                      default=True,
-                      help="""Controls generation of EnumTraits by the C++
-                              backend""")
-  parser.add_argument("input_file",
-                      type=str,
-                      nargs=1,
-                      help=".emb file to compile.")
-  return parser.parse_args(argv[1:])
+    parser = argparse.ArgumentParser(description="Emboss compiler")
+    parser.add_argument(
+        "--color-output",
+        default="if_tty",
+        choices=["always", "never", "if_tty", "auto"],
+        help="Print error messages using color.  'auto' is a synonym for 'if_tty'.",
+    )
+    parser.add_argument(
+        "--import-dir",
+        "-I",
+        dest="import_dirs",
+        action="append",
+        default=["."],
+        help="""A directory to use when searching for imported embs.  If no
+                import-dirs are specified, the current directory will be used.""",
+    )
+    parser.add_argument(
+        "--generate",
+        nargs=1,
+        choices=["cc"],
+        default="cc",
+        help="Which back end to use.  Currently only C++ is supported.",
+    )
+    parser.add_argument(
+        "--output-path",
+        nargs=1,
+        default=".",
+        help="Prefix path to use for the generated output file.  Defaults to '.'",
+    )
+    parser.add_argument(
+        "--output-file",
+        nargs=1,
+        help="""File name to be used for the generated output file.  Defaults to
+                input_file suffixed by '.h'""",
+    )
+    parser.add_argument(
+        "--cc-enum-traits",
+        action=argparse.BooleanOptionalAction,
+        default=True,
+        help="Controls generation of EnumTraits by the C++ backend",
+    )
+    parser.add_argument("input_file", type=str, nargs=1, help=".emb file to compile.")
+    return parser.parse_args(argv[1:])
 
 
 def main(argv):
-  flags = _parse_args(argv)
-  base_path = os.path.dirname(__file__) or "."
-  sys.path.append(base_path)
+    flags = _parse_args(argv)
+    base_path = os.path.dirname(__file__) or "."
+    sys.path.append(base_path)
 
-  from compiler.back_end.cpp import ( # pylint:disable=import-outside-toplevel
+    from compiler.back_end.cpp import ( # pylint:disable=import-outside-toplevel
     emboss_codegen_cpp, header_generator
-  )
-  from compiler.front_end import ( # pylint:disable=import-outside-toplevel
+    )
+    from compiler.front_end import ( # pylint:disable=import-outside-toplevel
     emboss_front_end
-  )
+    )
 
-  ir, _, errors =  emboss_front_end.parse_and_log_errors(
-      flags.input_file[0], flags.import_dirs, flags.color_output)
+    ir, _, errors = emboss_front_end.parse_and_log_errors(
+        flags.input_file[0], flags.import_dirs, flags.color_output
+    )
 
-  if errors:
-    return 1
+    if errors:
+        return 1
 
-  config = header_generator.Config(include_enum_traits=flags.cc_enum_traits)
-  header, errors = emboss_codegen_cpp.generate_headers_and_log_errors(
-      ir, flags.color_output, config)
+    config = header_generator.Config(include_enum_traits=flags.cc_enum_traits)
+    header, errors = emboss_codegen_cpp.generate_headers_and_log_errors(
+        ir, flags.color_output, config
+    )
 
-  if errors:
-    return 1
+    if errors:
+        return 1
 
-  if flags.output_file:
-    output_file = flags.output_file[0]
-  else:
-    output_file = flags.input_file[0] + ".h"
+    if flags.output_file:
+        output_file = flags.output_file[0]
+    else:
+        output_file = flags.input_file[0] + ".h"
 
-  output_filepath = os.path.join(flags.output_path[0], output_file)
-  os.makedirs(os.path.dirname(output_filepath), exist_ok=True)
+    output_filepath = os.path.join(flags.output_path[0], output_file)
+    os.makedirs(os.path.dirname(output_filepath), exist_ok=True)
 
-  with open(output_filepath, "w") as output:
-    output.write(header)
-  return 0
+    with open(output_filepath, "w") as output:
+        output.write(header)
+    return 0
 
 
 if __name__ == "__main__":
-  sys.exit(main(sys.argv))
+    sys.exit(main(sys.argv))
diff --git a/gen/sources.bzl b/gen/sources.bzl
new file mode 100644
index 0000000..3a1f135
--- /dev/null
+++ b/gen/sources.bzl
@@ -0,0 +1,83 @@
+# Copyright 2025 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Automatically generated by generate_build_files.py.
+# Do not edit this file directly.
+
+EMBOSSC_SOURCES = [
+    "compiler/__init__.py",
+    "compiler/back_end/__init__.py",
+    "compiler/back_end/cpp/__init__.py",
+    "compiler/back_end/cpp/attributes.py",
+    "compiler/back_end/cpp/emboss_codegen_cpp.py",
+    "compiler/back_end/cpp/generated_code_templates",
+    "compiler/back_end/cpp/header_generator.py",
+    "compiler/back_end/util/__init__.py",
+    "compiler/back_end/util/code_template.py",
+    "compiler/front_end/__init__.py",
+    "compiler/front_end/attribute_checker.py",
+    "compiler/front_end/attributes.py",
+    "compiler/front_end/constraints.py",
+    "compiler/front_end/dependency_checker.py",
+    "compiler/front_end/emboss_front_end.py",
+    "compiler/front_end/error_examples",
+    "compiler/front_end/expression_bounds.py",
+    "compiler/front_end/generated/cached_parser.py",
+    "compiler/front_end/glue.py",
+    "compiler/front_end/lr1.py",
+    "compiler/front_end/make_parser.py",
+    "compiler/front_end/module_ir.py",
+    "compiler/front_end/parser.py",
+    "compiler/front_end/prelude.emb",
+    "compiler/front_end/reserved_words",
+    "compiler/front_end/symbol_resolver.py",
+    "compiler/front_end/synthetics.py",
+    "compiler/front_end/tokenizer.py",
+    "compiler/front_end/type_check.py",
+    "compiler/front_end/write_inference.py",
+    "compiler/util/__init__.py",
+    "compiler/util/attribute_util.py",
+    "compiler/util/error.py",
+    "compiler/util/expression_parser.py",
+    "compiler/util/ir_data.py",
+    "compiler/util/ir_data_fields.py",
+    "compiler/util/ir_data_utils.py",
+    "compiler/util/ir_util.py",
+    "compiler/util/name_conversion.py",
+    "compiler/util/parser_types.py",
+    "compiler/util/parser_util.py",
+    "compiler/util/resources.py",
+    "compiler/util/simple_memoizer.py",
+    "compiler/util/traverse_ir.py",
+    "embossc",
+]
+
+EMBOSS_RUNTIME_CPP_SOURCES = [
+    "runtime/cpp/emboss_arithmetic.h",
+    "runtime/cpp/emboss_arithmetic_all_known_generated.h",
+    "runtime/cpp/emboss_arithmetic_maximum_operation_generated.h",
+    "runtime/cpp/emboss_array_view.h",
+    "runtime/cpp/emboss_bit_util.h",
+    "runtime/cpp/emboss_constant_view.h",
+    "runtime/cpp/emboss_cpp_types.h",
+    "runtime/cpp/emboss_cpp_util.h",
+    "runtime/cpp/emboss_defines.h",
+    "runtime/cpp/emboss_enum_view.h",
+    "runtime/cpp/emboss_maybe.h",
+    "runtime/cpp/emboss_memory_util.h",
+    "runtime/cpp/emboss_prelude.h",
+    "runtime/cpp/emboss_text_util.h",
+    "runtime/cpp/emboss_view_parameters.h",
+]
diff --git a/gen/sources.cmake b/gen/sources.cmake
new file mode 100644
index 0000000..60d009b
--- /dev/null
+++ b/gen/sources.cmake
@@ -0,0 +1,83 @@
+# Copyright 2025 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Automatically generated by generate_build_files.py.
+# Do not edit this file directly.
+
+set(EMBOSSC_SOURCES
+  "compiler/__init__.py"
+  "compiler/back_end/__init__.py"
+  "compiler/back_end/cpp/__init__.py"
+  "compiler/back_end/cpp/attributes.py"
+  "compiler/back_end/cpp/emboss_codegen_cpp.py"
+  "compiler/back_end/cpp/generated_code_templates"
+  "compiler/back_end/cpp/header_generator.py"
+  "compiler/back_end/util/__init__.py"
+  "compiler/back_end/util/code_template.py"
+  "compiler/front_end/__init__.py"
+  "compiler/front_end/attribute_checker.py"
+  "compiler/front_end/attributes.py"
+  "compiler/front_end/constraints.py"
+  "compiler/front_end/dependency_checker.py"
+  "compiler/front_end/emboss_front_end.py"
+  "compiler/front_end/error_examples"
+  "compiler/front_end/expression_bounds.py"
+  "compiler/front_end/generated/cached_parser.py"
+  "compiler/front_end/glue.py"
+  "compiler/front_end/lr1.py"
+  "compiler/front_end/make_parser.py"
+  "compiler/front_end/module_ir.py"
+  "compiler/front_end/parser.py"
+  "compiler/front_end/prelude.emb"
+  "compiler/front_end/reserved_words"
+  "compiler/front_end/symbol_resolver.py"
+  "compiler/front_end/synthetics.py"
+  "compiler/front_end/tokenizer.py"
+  "compiler/front_end/type_check.py"
+  "compiler/front_end/write_inference.py"
+  "compiler/util/__init__.py"
+  "compiler/util/attribute_util.py"
+  "compiler/util/error.py"
+  "compiler/util/expression_parser.py"
+  "compiler/util/ir_data.py"
+  "compiler/util/ir_data_fields.py"
+  "compiler/util/ir_data_utils.py"
+  "compiler/util/ir_util.py"
+  "compiler/util/name_conversion.py"
+  "compiler/util/parser_types.py"
+  "compiler/util/parser_util.py"
+  "compiler/util/resources.py"
+  "compiler/util/simple_memoizer.py"
+  "compiler/util/traverse_ir.py"
+  "embossc"
+)
+
+set(EMBOSS_RUNTIME_CPP_SOURCES
+  "runtime/cpp/emboss_arithmetic.h"
+  "runtime/cpp/emboss_arithmetic_all_known_generated.h"
+  "runtime/cpp/emboss_arithmetic_maximum_operation_generated.h"
+  "runtime/cpp/emboss_array_view.h"
+  "runtime/cpp/emboss_bit_util.h"
+  "runtime/cpp/emboss_constant_view.h"
+  "runtime/cpp/emboss_cpp_types.h"
+  "runtime/cpp/emboss_cpp_util.h"
+  "runtime/cpp/emboss_defines.h"
+  "runtime/cpp/emboss_enum_view.h"
+  "runtime/cpp/emboss_maybe.h"
+  "runtime/cpp/emboss_memory_util.h"
+  "runtime/cpp/emboss_prelude.h"
+  "runtime/cpp/emboss_text_util.h"
+  "runtime/cpp/emboss_view_parameters.h"
+)
diff --git a/gen/sources.gni b/gen/sources.gni
new file mode 100644
index 0000000..6207e5b
--- /dev/null
+++ b/gen/sources.gni
@@ -0,0 +1,83 @@
+# Copyright 2025 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# Automatically generated by generate_build_files.py.
+# Do not edit this file directly.
+
+embossc_sources = [
+  "compiler/__init__.py",
+  "compiler/back_end/__init__.py",
+  "compiler/back_end/cpp/__init__.py",
+  "compiler/back_end/cpp/attributes.py",
+  "compiler/back_end/cpp/emboss_codegen_cpp.py",
+  "compiler/back_end/cpp/generated_code_templates",
+  "compiler/back_end/cpp/header_generator.py",
+  "compiler/back_end/util/__init__.py",
+  "compiler/back_end/util/code_template.py",
+  "compiler/front_end/__init__.py",
+  "compiler/front_end/attribute_checker.py",
+  "compiler/front_end/attributes.py",
+  "compiler/front_end/constraints.py",
+  "compiler/front_end/dependency_checker.py",
+  "compiler/front_end/emboss_front_end.py",
+  "compiler/front_end/error_examples",
+  "compiler/front_end/expression_bounds.py",
+  "compiler/front_end/generated/cached_parser.py",
+  "compiler/front_end/glue.py",
+  "compiler/front_end/lr1.py",
+  "compiler/front_end/make_parser.py",
+  "compiler/front_end/module_ir.py",
+  "compiler/front_end/parser.py",
+  "compiler/front_end/prelude.emb",
+  "compiler/front_end/reserved_words",
+  "compiler/front_end/symbol_resolver.py",
+  "compiler/front_end/synthetics.py",
+  "compiler/front_end/tokenizer.py",
+  "compiler/front_end/type_check.py",
+  "compiler/front_end/write_inference.py",
+  "compiler/util/__init__.py",
+  "compiler/util/attribute_util.py",
+  "compiler/util/error.py",
+  "compiler/util/expression_parser.py",
+  "compiler/util/ir_data.py",
+  "compiler/util/ir_data_fields.py",
+  "compiler/util/ir_data_utils.py",
+  "compiler/util/ir_util.py",
+  "compiler/util/name_conversion.py",
+  "compiler/util/parser_types.py",
+  "compiler/util/parser_util.py",
+  "compiler/util/resources.py",
+  "compiler/util/simple_memoizer.py",
+  "compiler/util/traverse_ir.py",
+  "embossc",
+]
+
+emboss_runtime_cpp_sources = [
+  "runtime/cpp/emboss_arithmetic.h",
+  "runtime/cpp/emboss_arithmetic_all_known_generated.h",
+  "runtime/cpp/emboss_arithmetic_maximum_operation_generated.h",
+  "runtime/cpp/emboss_array_view.h",
+  "runtime/cpp/emboss_bit_util.h",
+  "runtime/cpp/emboss_constant_view.h",
+  "runtime/cpp/emboss_cpp_types.h",
+  "runtime/cpp/emboss_cpp_util.h",
+  "runtime/cpp/emboss_defines.h",
+  "runtime/cpp/emboss_enum_view.h",
+  "runtime/cpp/emboss_maybe.h",
+  "runtime/cpp/emboss_memory_util.h",
+  "runtime/cpp/emboss_prelude.h",
+  "runtime/cpp/emboss_text_util.h",
+  "runtime/cpp/emboss_view_parameters.h",
+]
diff --git a/gen/sources.json b/gen/sources.json
new file mode 100644
index 0000000..46212da
--- /dev/null
+++ b/gen/sources.json
@@ -0,0 +1,66 @@
+{
+    "embossc_sources": [
+        "compiler/__init__.py",
+        "compiler/back_end/__init__.py",
+        "compiler/back_end/cpp/__init__.py",
+        "compiler/back_end/cpp/attributes.py",
+        "compiler/back_end/cpp/emboss_codegen_cpp.py",
+        "compiler/back_end/cpp/generated_code_templates",
+        "compiler/back_end/cpp/header_generator.py",
+        "compiler/back_end/util/__init__.py",
+        "compiler/back_end/util/code_template.py",
+        "compiler/front_end/__init__.py",
+        "compiler/front_end/attribute_checker.py",
+        "compiler/front_end/attributes.py",
+        "compiler/front_end/constraints.py",
+        "compiler/front_end/dependency_checker.py",
+        "compiler/front_end/emboss_front_end.py",
+        "compiler/front_end/error_examples",
+        "compiler/front_end/expression_bounds.py",
+        "compiler/front_end/generated/cached_parser.py",
+        "compiler/front_end/glue.py",
+        "compiler/front_end/lr1.py",
+        "compiler/front_end/make_parser.py",
+        "compiler/front_end/module_ir.py",
+        "compiler/front_end/parser.py",
+        "compiler/front_end/prelude.emb",
+        "compiler/front_end/reserved_words",
+        "compiler/front_end/symbol_resolver.py",
+        "compiler/front_end/synthetics.py",
+        "compiler/front_end/tokenizer.py",
+        "compiler/front_end/type_check.py",
+        "compiler/front_end/write_inference.py",
+        "compiler/util/__init__.py",
+        "compiler/util/attribute_util.py",
+        "compiler/util/error.py",
+        "compiler/util/expression_parser.py",
+        "compiler/util/ir_data.py",
+        "compiler/util/ir_data_fields.py",
+        "compiler/util/ir_data_utils.py",
+        "compiler/util/ir_util.py",
+        "compiler/util/name_conversion.py",
+        "compiler/util/parser_types.py",
+        "compiler/util/parser_util.py",
+        "compiler/util/resources.py",
+        "compiler/util/simple_memoizer.py",
+        "compiler/util/traverse_ir.py",
+        "embossc"
+    ],
+    "emboss_runtime_cpp_sources": [
+        "runtime/cpp/emboss_arithmetic.h",
+        "runtime/cpp/emboss_arithmetic_all_known_generated.h",
+        "runtime/cpp/emboss_arithmetic_maximum_operation_generated.h",
+        "runtime/cpp/emboss_array_view.h",
+        "runtime/cpp/emboss_bit_util.h",
+        "runtime/cpp/emboss_constant_view.h",
+        "runtime/cpp/emboss_cpp_types.h",
+        "runtime/cpp/emboss_cpp_util.h",
+        "runtime/cpp/emboss_defines.h",
+        "runtime/cpp/emboss_enum_view.h",
+        "runtime/cpp/emboss_maybe.h",
+        "runtime/cpp/emboss_memory_util.h",
+        "runtime/cpp/emboss_prelude.h",
+        "runtime/cpp/emboss_text_util.h",
+        "runtime/cpp/emboss_view_parameters.h"
+    ]
+}
diff --git a/runtime/cpp/emboss_array_view.h b/runtime/cpp/emboss_array_view.h
index 674b2ad..fa8ccd3 100644
--- a/runtime/cpp/emboss_array_view.h
+++ b/runtime/cpp/emboss_array_view.h
@@ -56,7 +56,7 @@
 
   explicit ElementViewIterator(const GenericArrayView array_view,
                                ::std::ptrdiff_t index)
-      : array_view_(array_view), view_(array_view[index]), index_(index) {}
+      : array_view_(array_view), view_(array_view.at(index)), index_(index) {}
 
   ElementViewIterator() = default;
 
@@ -66,7 +66,7 @@
 
   ElementViewIterator &operator+=(difference_type d) {
     index_ += (kDirection == ElementViewIteratorDirection::kForward ? d : -d);
-    view_ = array_view_[index_];
+    view_ = array_view_.at(index_);
     return *this;
   }
 
@@ -178,9 +178,15 @@
       : parameters_{parameters...}, buffer_{buffer} {}
 
   ElementView operator[](::std::size_t index) const {
-    return IndexOperatorHelper<sizeof...(ElementViewParameterTypes) ==
-                               0>::ConstructElement(parameters_, buffer_,
-                                                    index);
+    return IndexOperatorHelper<(sizeof...(ElementViewParameterTypes) ==
+                                0)>::UncheckedConstructElement(parameters_,
+                                                               buffer_, index);
+  }
+
+  ElementView at(::std::size_t index) const {
+    return IndexOperatorHelper<(sizeof...(ElementViewParameterTypes) ==
+                                0)>::ConstructElement(parameters_, buffer_,
+                                                      index, ElementCount());
   }
 
   ForwardIterator begin() const { return ForwardIterator(*this, 0); }
@@ -316,10 +322,18 @@
   struct IndexOperatorHelper {
     static ElementView ConstructElement(
         const ::std::tuple<ElementViewParameterTypes...> &parameters,
+        BufferType buffer, ::std::size_t index, ::std::size_t size) {
+      return IndexOperatorHelper<
+          (sizeof...(ElementViewParameterTypes) == 1 + sizeof...(N)), N...,
+          sizeof...(N)>::ConstructElement(parameters, buffer, index, size);
+    }
+
+    static ElementView UncheckedConstructElement(
+        const ::std::tuple<ElementViewParameterTypes...> &parameters,
         BufferType buffer, ::std::size_t index) {
       return IndexOperatorHelper<
-          sizeof...(ElementViewParameterTypes) == 1 + sizeof...(N), N...,
-          sizeof...(N)>::ConstructElement(parameters, buffer, index);
+          (sizeof...(ElementViewParameterTypes) == 1 + sizeof...(N)), N...,
+          sizeof...(N)>::UncheckedConstructElement(parameters, buffer, index);
     }
   };
 
@@ -327,6 +341,18 @@
   struct IndexOperatorHelper<true, N...> {
     static ElementView ConstructElement(
         const ::std::tuple<ElementViewParameterTypes...> &parameters,
+        BufferType buffer, ::std::size_t index, ::std::size_t size) {
+      return ElementView(
+          ::std::get<N>(parameters)...,
+          index < 0 || index >= size
+              ? typename BufferType::template OffsetStorageType<kElementSize,
+                                                                0>(nullptr)
+              : buffer.template GetOffsetStorage<kElementSize, 0>(
+                    kElementSize * index, kElementSize));
+    }
+
+    static ElementView UncheckedConstructElement(
+        const ::std::tuple<ElementViewParameterTypes...> &parameters,
         BufferType buffer, ::std::size_t index) {
       return ElementView(::std::get<N>(parameters)...,
                          buffer.template GetOffsetStorage<kElementSize, 0>(
diff --git a/runtime/cpp/emboss_defines.h b/runtime/cpp/emboss_defines.h
index 5677874..24b5af0 100644
--- a/runtime/cpp/emboss_defines.h
+++ b/runtime/cpp/emboss_defines.h
@@ -66,9 +66,17 @@
 //
 // By default, checks are only enabled on non-NDEBUG builds.  (Note that all
 // translation units MUST be built with the same value of NDEBUG!)
+//
+// The EMBOSS_SKIP_CHECKS parameter allows all CHECKs to be compiled out
+// without -DNDEBUG; this is useful for testing.
 #if !defined(EMBOSS_CHECK)
+#if defined(EMBOSS_SKIP_CHECKS)
+#define EMBOSS_CHECK(x) ((void)0)
+#define EMBOSS_CHECK_ABORTS false
+#else  // !defined(EMBOSS_SKIP_CHECKS)
 #define EMBOSS_CHECK(x) assert((x))
 #define EMBOSS_CHECK_ABORTS (!(NDEBUG))
+#endif  // defined(EMBOSS_SKIP_CHECKS)
 #endif  // !defined(EMBOSS_CHECK)
 
 #if !defined(EMBOSS_CHECK_ABORTS)
@@ -153,6 +161,27 @@
                   static_cast</**/ ::std::uintptr_t>((offset)))
 #endif  // !defined(EMBOSS_CHECK_POINTER_ALIGNMENT)
 
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115033
+//
+// This affects Emboss: without the fix in the appropriate bug, we get a
+// miscompilation for some Emboss code, including some unit tests.
+//
+// It is not known whether the workaround on the Emboss side is complete, so
+// the recommendation is to move to a version of GCC that is not affected.
+// However, changing toolchains can be difficult, so we do provide a
+// workaround.
+#if !defined(EMBOSS_GCC_BUG_115033)
+#if defined(__clang__)
+#define EMBOSS_GCC_BUG_115033 0
+#elif __GNUC__ >= 12 && __GNUC__ <= 13
+#define EMBOSS_GCC_BUG_115033 1
+#elif __GNUC__ == 14 && __GNUC_MINOR__ < 2
+#define EMBOSS_GCC_BUG_115033 1
+#else
+#define EMBOSS_GCC_BUG_115033 0
+#endif
+#endif
+
 // EMBOSS_NO_OPTIMIZATIONS is used to turn off all system-specific
 // optimizations.  This is mostly intended for testing, but could be used if
 // optimizations are causing problems.
diff --git a/runtime/cpp/emboss_memory_util.h b/runtime/cpp/emboss_memory_util.h
index 09be2f1..fca71c9 100644
--- a/runtime/cpp/emboss_memory_util.h
+++ b/runtime/cpp/emboss_memory_util.h
@@ -412,8 +412,28 @@
   explicit ContiguousBuffer(::std::nullptr_t) : bytes_{nullptr}, size_{0} {}
 
   // Implicitly construct or assign a ContiguousBuffer from a ContiguousBuffer.
+#if !EMBOSS_GCC_BUG_115033
   ContiguousBuffer(const ContiguousBuffer &other) = default;
-  ContiguousBuffer& operator=(const ContiguousBuffer& other) = default;
+  ContiguousBuffer &operator=(const ContiguousBuffer &other) = default;
+#else
+  // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115033 for details on the
+  // bug (determined by bisecting GCC).
+  // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114207 may also be relevant.
+  //
+  // A minimized example is available at https://godbolt.org/z/489z7z135
+  //
+  // It is not entirely clear how these definitions work around the GCC bug,
+  // but they appear to.  One notable difference (and also the main reason that
+  // we only use these definitions for affected versions of GCC) is that they
+  // change the ABI of ContiguousBuffer, at least in the minimized case.
+  ContiguousBuffer(const ContiguousBuffer &other)
+      : bytes_{other.bytes_}, size_{other.size_} {}
+  ContiguousBuffer &operator=(const ContiguousBuffer &other) {
+    bytes_ = other.bytes_;
+    size_ = other.size_;
+    return *this;
+  }
+#endif
 
   // Explicitly construct a ContiguousBuffers from another, compatible
   // ContiguousBuffer.  A compatible ContiguousBuffer has an
diff --git a/runtime/cpp/test/emboss_cpp_types_test.cc b/runtime/cpp/test/emboss_cpp_types_test.cc
index c8976b9..e0d6308 100644
--- a/runtime/cpp/test/emboss_cpp_types_test.cc
+++ b/runtime/cpp/test/emboss_cpp_types_test.cc
@@ -12,6 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#include <cstddef>
+
 #include "runtime/cpp/emboss_cpp_types.h"
 
 #include "gtest/gtest.h"
diff --git a/runtime/cpp/test/emboss_memory_util_test.cc b/runtime/cpp/test/emboss_memory_util_test.cc
index 6399b4c..1831085 100644
--- a/runtime/cpp/test/emboss_memory_util_test.cc
+++ b/runtime/cpp/test/emboss_memory_util_test.cc
@@ -14,11 +14,13 @@
 
 #include <array>
 #include <string>
+#include <type_traits>
+#include <vector>
+
 #if __cplusplus >= 201703L
 #include <cstddef>  // std::byte
 #include <string_view>
 #endif  // __cplusplus >= 201703L
-#include <vector>
 
 #include "gtest/gtest.h"
 #include "runtime/cpp/emboss_memory_util.h"
diff --git a/scripts/build_helpers/generate_build_files.py b/scripts/build_helpers/generate_build_files.py
new file mode 100755
index 0000000..480b3b2
--- /dev/null
+++ b/scripts/build_helpers/generate_build_files.py
@@ -0,0 +1,128 @@
+#!/usr/bin/env python3
+# Copyright 2025 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Generates build helper files from `build.json`."""
+
+import json
+import os
+
+COPYRIGHT_HEADER = """# Copyright 2025 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""
+
+
+def read_build_json(file_path):
+    """Reads build.json, strips comments, and returns the parsed JSON data."""
+    with open(file_path, "r") as f:
+        # Simple comment stripping for JSONC format
+        content = "".join(line for line in f if not line.strip().startswith("//"))
+    return json.loads(content)
+
+
+def generate_sources_json(output_dir, data):
+    """Generates gen/sources.json."""
+    output_path = os.path.join(output_dir, "sources.json")
+    with open(output_path, "w") as f:
+        json.dump(data, f, indent=4)
+        f.write("\n")
+    print(f"Generated {output_path}")
+
+
+def generate_sources_bzl(output_dir, data):
+    """Generates gen/sources.bzl."""
+    output_path = os.path.join(output_dir, "sources.bzl")
+    with open(output_path, "w") as f:
+        f.write(COPYRIGHT_HEADER)
+        f.write("\n\n")
+        f.write("# Automatically generated by generate_build_files.py.\n")
+        f.write("# Do not edit this file directly.\n")
+        f.write("\n")
+        f.write("EMBOSSC_SOURCES = [\n")
+        for source in data["embossc_sources"]:
+            f.write(f'    "{source}",\n')
+        f.write("]\n\n")
+        f.write("EMBOSS_RUNTIME_CPP_SOURCES = [\n")
+        for source in data["emboss_runtime_cpp_sources"]:
+            f.write(f'    "{source}",\n')
+        f.write("]\n")
+    print(f"Generated {output_path}")
+
+
+def generate_sources_cmake(output_dir, data):
+    """Generates gen/sources.cmake."""
+    output_path = os.path.join(output_dir, "sources.cmake")
+    with open(output_path, "w") as f:
+        f.write(COPYRIGHT_HEADER)
+        f.write("\n\n")
+        f.write("# Automatically generated by generate_build_files.py.\n")
+        f.write("# Do not edit this file directly.\n\n")
+        f.write("set(EMBOSSC_SOURCES\n")
+        for source in data["embossc_sources"]:
+            f.write(f'  "{source}"\n')
+        f.write(")\n\n")
+        f.write("set(EMBOSS_RUNTIME_CPP_SOURCES\n")
+        for source in data["emboss_runtime_cpp_sources"]:
+            f.write(f'  "{source}"\n')
+        f.write(")\n")
+    print(f"Generated {output_path}")
+
+
+def generate_sources_gni(output_dir, data):
+    """Generates gen/sources.gni."""
+    output_path = os.path.join(output_dir, "sources.gni")
+    with open(output_path, "w") as f:
+        f.write(COPYRIGHT_HEADER)
+        f.write("\n\n")
+        f.write("# Automatically generated by generate_build_files.py.\n")
+        f.write("# Do not edit this file directly.\n\n")
+        f.write("embossc_sources = [\n")
+        for source in data["embossc_sources"]:
+            f.write(f'  "{source}",\n')
+        f.write("]\n\n")
+        f.write("emboss_runtime_cpp_sources = [\n")
+        for source in data["emboss_runtime_cpp_sources"]:
+            f.write(f'  "{source}",\n')
+        f.write("]\n")
+    print(f"Generated {output_path}")
+
+
+def main():
+    workspace_root = os.environ.get("BUILD_WORKSPACE_DIRECTORY", os.getcwd())
+    build_json_path = os.path.join(workspace_root, "build.json")
+    gen_dir = os.path.join(workspace_root, "gen")
+
+    os.makedirs(gen_dir, exist_ok=True)
+
+    data = read_build_json(build_json_path)
+
+    generate_sources_json(gen_dir, data)
+    generate_sources_bzl(gen_dir, data)
+    generate_sources_cmake(gen_dir, data)
+    generate_sources_gni(gen_dir, data)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/scripts/build_helpers/manage_build_json.py b/scripts/build_helpers/manage_build_json.py
new file mode 100755
index 0000000..3d356c1
--- /dev/null
+++ b/scripts/build_helpers/manage_build_json.py
@@ -0,0 +1,193 @@
+#!/usr/bin/env python3
+
+# Copyright 2025 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Creates and validates the `build.json` file."""
+
+import argparse
+import json
+import os
+import subprocess
+import sys
+
+# The Bazel targets that define the embossc compiler sources.
+EMBOSSC_TARGETS = [
+    "//compiler/back_end/cpp:emboss_codegen_cpp",
+    "//compiler/front_end:emboss_front_end",
+]
+
+# The Bazel target for the C++ runtime sources.
+RUNTIME_CPP_TARGET = "//runtime/cpp:cpp_utils"
+
+
+def get_bazel_query_output(query):
+    """Runs a Bazel query and returns the output as a list of strings."""
+    result = subprocess.run(
+        ["bazel", "query", query],
+        capture_output=True,
+        text=True,
+        check=True,
+    )
+    return result.stdout.strip().split("\n")
+
+
+def get_source_files_for_targets(targets):
+    """Queries Bazel for all source files in the transitive dependencies."""
+    query = f"kind('source file', deps({'+'.join(targets)}))"
+    output = get_bazel_query_output(query)
+    return sorted(
+        [
+            f.replace("//", "").replace(":", "/")
+            for f in output
+            if f.startswith("//") and not f.startswith("//external")
+        ]
+    )
+
+
+def read_build_json(file_path):
+    """Reads build.json, strips comments, and returns the parsed JSON data."""
+    with open(file_path, "r") as f:
+        content = "".join(line for line in f if not line.strip().startswith("//"))
+    return json.loads(content)
+
+
+def find_init_py_files(source_files):
+    """Finds all __init__.py files in the directories of the source files."""
+    init_py_files = set()
+    checked_dirs = set()
+
+    for source_file in source_files:
+        dir_path = os.path.dirname(source_file)
+        while dir_path and dir_path not in checked_dirs:
+            checked_dirs.add(dir_path)
+            init_py = os.path.join(dir_path, "__init__.py")
+            if os.path.exists(init_py):
+                init_py_files.add(init_py)
+            # Move to the parent directory
+            parent_dir = os.path.dirname(dir_path)
+            if parent_dir == dir_path:  # Root directory
+                break
+            dir_path = parent_dir
+
+    return sorted(list(init_py_files))
+
+
+def generate_build_json(output_path):
+    """Generates the build.json file from Bazel sources."""
+    print("Generating fresh source lists from Bazel...")
+    embossc_sources = get_source_files_for_targets(EMBOSSC_TARGETS)
+    embossc_sources.append("embossc")
+    init_py_sources = find_init_py_files(embossc_sources)
+    all_embossc_sources = sorted(list(set(embossc_sources + init_py_sources)))
+
+    runtime_cpp_sources = get_source_files_for_targets([RUNTIME_CPP_TARGET])
+
+    build_data = {
+        "embossc_sources": all_embossc_sources,
+        "emboss_runtime_cpp_sources": runtime_cpp_sources,
+    }
+
+    # Use json.dumps to get a formatted string, then inject comments.
+    json_string = json.dumps(build_data, indent=2)
+    json_string = json_string.replace(
+        '"embossc_sources":',
+        '// A list of all source files required to build the Emboss compiler.\n  "embossc_sources":',
+    )
+    json_string = json_string.replace(
+        '"emboss_runtime_cpp_sources":',
+        '// A list of all source files required for the Emboss C++ runtime.\n  "emboss_runtime_cpp_sources":',
+    )
+
+    with open(output_path, "w") as f:
+        f.write(json_string)
+        f.write("\n")
+
+    print(f"Successfully generated {output_path}")
+    return 0
+
+
+def validate_build_json(file_path):
+    """Validates that the on-disk build.json file is up-to-date."""
+    print("Generating fresh source lists from Bazel for validation...")
+    fresh_embossc_sources = get_source_files_for_targets(EMBOSSC_TARGETS)
+    fresh_embossc_sources.append("embossc")
+    init_py_sources = find_init_py_files(fresh_embossc_sources)
+    all_fresh_embossc_sources = sorted(
+        list(set(fresh_embossc_sources + init_py_sources))
+    )
+    fresh_runtime_cpp_sources = get_source_files_for_targets([RUNTIME_CPP_TARGET])
+
+    print(f"Reading existing sources from {file_path}...")
+    on_disk_data = read_build_json(file_path)
+    on_disk_embossc_sources = on_disk_data.get("embossc_sources", [])
+    on_disk_runtime_cpp_sources = on_disk_data.get("emboss_runtime_cpp_sources", [])
+
+    embossc_diff = set(all_fresh_embossc_sources) ^ set(on_disk_embossc_sources)
+    runtime_diff = set(fresh_runtime_cpp_sources) ^ set(on_disk_runtime_cpp_sources)
+
+    if not embossc_diff and not runtime_diff:
+        print("build.json is up-to-date.")
+        return 0
+
+    print("\nERROR: build.json is out of date!", file=sys.stderr)
+
+    def print_diff(title, fresh_set, on_disk_set):
+        added = sorted(list(fresh_set - on_disk_set))
+        removed = sorted(list(on_disk_set - fresh_set))
+        if added or removed:
+            print(f"  {title}:", file=sys.stderr)
+            for f in added:
+                print(f"    + {f}", file=sys.stderr)
+            for f in removed:
+                print(f"    - {f}", file=sys.stderr)
+
+    print_diff(
+        "embossc_sources",
+        set(fresh_embossc_sources),
+        set(on_disk_embossc_sources),
+    )
+    print_diff(
+        "emboss_runtime_cpp_sources",
+        set(fresh_runtime_cpp_sources),
+        set(on_disk_runtime_cpp_sources),
+    )
+
+    print(
+        "\nPlease run 'scripts/build_helpers/manage_build_json.py' to update.",
+        file=sys.stderr,
+    )
+    return 1
+
+
+def main():
+    parser = argparse.ArgumentParser(description="Manage the build.json file.")
+    parser.add_argument(
+        "--validate",
+        action="store_true",
+        help="Validate that build.json is up-to-date.",
+    )
+    args = parser.parse_args()
+
+    workspace_root = os.environ.get("BUILD_WORKSPACE_DIRECTORY", os.getcwd())
+    build_json_path = os.path.join(workspace_root, "build.json")
+
+    if args.validate:
+        return validate_build_json(build_json_path)
+    else:
+        return generate_build_json(build_json_path)
+
+
+if __name__ == "__main__":
+    sys.exit(main())
diff --git a/testdata/BUILD b/testdata/BUILD
index f8a1be7..95716da 100644
--- a/testdata/BUILD
+++ b/testdata/BUILD
@@ -36,6 +36,11 @@
     ],
 )
 
+
+
+exports_files(glob(["**/*.emb"]))
+
+
 filegroup(
     name = "test_embs",
     srcs = [
@@ -57,6 +62,7 @@
         "imported.emb",
         "imported_genfiles.emb",
         "importer.emb",
+        "importer2.emb",
         "int_sizes.emb",
         "nested_structure.emb",
         "next_keyword.emb",
diff --git a/testdata/golden/span_se_log_file_status.ir.txt b/testdata/golden/span_se_log_file_status.ir.txt
index b1bfef8..b880c1c 100644
--- a/testdata/golden/span_se_log_file_status.ir.txt
+++ b/testdata/golden/span_se_log_file_status.ir.txt
@@ -3,126 +3,36 @@
     {
       "name": {
         "text": "byte_order",
-        "source_location": {
-          "start": {
-            "line": 17,
-            "column": 11
-          },
-          "end": {
-            "line": 17,
-            "column": 21
-          },
-          "is_synthetic": false
-        }
+        "source_location": "17:11-17:21"
       },
       "value": {
         "string_constant": {
           "text": "LittleEndian",
-          "source_location": {
-            "start": {
-              "line": 17,
-              "column": 23
-            },
-            "end": {
-              "line": 17,
-              "column": 37
-            },
-            "is_synthetic": false
-          }
+          "source_location": "17:23-17:37"
         },
-        "source_location": {
-          "start": {
-            "line": 17,
-            "column": 23
-          },
-          "end": {
-            "line": 17,
-            "column": 37
-          },
-          "is_synthetic": false
-        }
+        "source_location": "17:23-17:37"
       },
       "is_default": true,
-      "source_location": {
-        "start": {
-          "line": 17,
-          "column": 1
-        },
-        "end": {
-          "line": 17,
-          "column": 38
-        },
-        "is_synthetic": false
-      }
+      "source_location": "17:1-17:38"
     },
     {
       "name": {
         "text": "namespace",
-        "source_location": {
-          "start": {
-            "line": 18,
-            "column": 8
-          },
-          "end": {
-            "line": 18,
-            "column": 17
-          },
-          "is_synthetic": false
-        }
+        "source_location": "18:8-18:17"
       },
       "value": {
         "string_constant": {
           "text": "emboss::test",
-          "source_location": {
-            "start": {
-              "line": 18,
-              "column": 19
-            },
-            "end": {
-              "line": 18,
-              "column": 33
-            },
-            "is_synthetic": false
-          }
+          "source_location": "18:19-18:33"
         },
-        "source_location": {
-          "start": {
-            "line": 18,
-            "column": 19
-          },
-          "end": {
-            "line": 18,
-            "column": 33
-          },
-          "is_synthetic": false
-        }
+        "source_location": "18:19-18:33"
       },
-      "is_default": false,
       "back_end": {
         "text": "cpp",
-        "source_location": {
-          "start": {
-            "line": 18,
-            "column": 2
-          },
-          "end": {
-            "line": 18,
-            "column": 7
-          },
-          "is_synthetic": false
-        }
+        "source_location": "18:2-18:7"
       },
-      "source_location": {
-        "start": {
-          "line": 18,
-          "column": 1
-        },
-        "end": {
-          "line": 20,
-          "column": 1
-        },
-        "is_synthetic": false
-      }
+      "is_default": false,
+      "source_location": "18:1-20:1"
     }
   ],
   "type": [
@@ -134,68 +44,18 @@
               "start": {
                 "constant": {
                   "value": "0",
-                  "source_location": {
-                    "start": {
-                      "line": 22,
-                      "column": 3
-                    },
-                    "end": {
-                      "line": 22,
-                      "column": 4
-                    },
-                    "is_synthetic": false
-                  }
+                  "source_location": "22:3-22:4"
                 },
-                "source_location": {
-                  "start": {
-                    "line": 22,
-                    "column": 3
-                  },
-                  "end": {
-                    "line": 22,
-                    "column": 4
-                  },
-                  "is_synthetic": false
-                }
+                "source_location": "22:3-22:4"
               },
               "size": {
                 "constant": {
                   "value": "4",
-                  "source_location": {
-                    "start": {
-                      "line": 22,
-                      "column": 8
-                    },
-                    "end": {
-                      "line": 22,
-                      "column": 9
-                    },
-                    "is_synthetic": false
-                  }
+                  "source_location": "22:8-22:9"
                 },
-                "source_location": {
-                  "start": {
-                    "line": 22,
-                    "column": 8
-                  },
-                  "end": {
-                    "line": 22,
-                    "column": 9
-                  },
-                  "is_synthetic": false
-                }
+                "source_location": "22:8-22:9"
               },
-              "source_location": {
-                "start": {
-                  "line": 22,
-                  "column": 3
-                },
-                "end": {
-                  "line": 22,
-                  "column": 10
-                },
-                "is_synthetic": false
-              }
+              "source_location": "22:3-22:10"
             },
             "type": {
               "atomic_type": {
@@ -203,187 +63,48 @@
                   "source_name": [
                     {
                       "text": "UInt",
-                      "source_location": {
-                        "start": {
-                          "line": 22,
-                          "column": 13
-                        },
-                        "end": {
-                          "line": 22,
-                          "column": 17
-                        },
-                        "is_synthetic": false
-                      }
+                      "source_location": "22:13-22:17"
                     }
                   ],
-                  "source_location": {
-                    "start": {
-                      "line": 22,
-                      "column": 13
-                    },
-                    "end": {
-                      "line": 22,
-                      "column": 17
-                    },
-                    "is_synthetic": false
-                  }
+                  "source_location": "22:13-22:17"
                 },
-                "source_location": {
-                  "start": {
-                    "line": 22,
-                    "column": 13
-                  },
-                  "end": {
-                    "line": 22,
-                    "column": 17
-                  },
-                  "is_synthetic": false
-                }
+                "source_location": "22:13-22:17"
               },
-              "source_location": {
-                "start": {
-                  "line": 22,
-                  "column": 13
-                },
-                "end": {
-                  "line": 22,
-                  "column": 17
-                },
-                "is_synthetic": false
-              }
+              "source_location": "22:13-22:17"
             },
             "name": {
               "name": {
                 "text": "file_state",
-                "source_location": {
-                  "start": {
-                    "line": 22,
-                    "column": 25
-                  },
-                  "end": {
-                    "line": 22,
-                    "column": 35
-                  },
-                  "is_synthetic": false
-                }
+                "source_location": "22:25-22:35"
               },
-              "source_location": {
-                "start": {
-                  "line": 22,
-                  "column": 25
-                },
-                "end": {
-                  "line": 22,
-                  "column": 35
-                },
-                "is_synthetic": false
-              }
-            },
-            "source_location": {
-              "start": {
-                "line": 22,
-                "column": 3
-              },
-              "end": {
-                "line": 22,
-                "column": 35
-              }
+              "source_location": "22:25-22:35"
             },
             "existence_condition": {
-              "source_location": {
-                "start": {
-                  "line": 22,
-                  "column": 3
-                },
-                "end": {
-                  "line": 22,
-                  "column": 35
-                },
-                "is_synthetic": false
-              },
               "boolean_constant": {
-                "source_location": {
-                  "start": {
-                    "line": 22,
-                    "column": 3
-                  },
-                  "end": {
-                    "line": 22,
-                    "column": 35
-                  },
-                  "is_synthetic": false
-                },
-                "value": true
-              }
-            }
+                "value": true,
+                "source_location": "22:3-22:35"
+              },
+              "source_location": "22:3-22:35"
+            },
+            "source_location": "22:3-22:35"
           },
           {
             "location": {
               "start": {
                 "constant": {
                   "value": "4",
-                  "source_location": {
-                    "start": {
-                      "line": 23,
-                      "column": 3
-                    },
-                    "end": {
-                      "line": 23,
-                      "column": 4
-                    },
-                    "is_synthetic": false
-                  }
+                  "source_location": "23:3-23:4"
                 },
-                "source_location": {
-                  "start": {
-                    "line": 23,
-                    "column": 3
-                  },
-                  "end": {
-                    "line": 23,
-                    "column": 4
-                  },
-                  "is_synthetic": false
-                }
+                "source_location": "23:3-23:4"
               },
               "size": {
                 "constant": {
                   "value": "12",
-                  "source_location": {
-                    "start": {
-                      "line": 23,
-                      "column": 8
-                    },
-                    "end": {
-                      "line": 23,
-                      "column": 10
-                    },
-                    "is_synthetic": false
-                  }
+                  "source_location": "23:8-23:10"
                 },
-                "source_location": {
-                  "start": {
-                    "line": 23,
-                    "column": 8
-                  },
-                  "end": {
-                    "line": 23,
-                    "column": 10
-                  },
-                  "is_synthetic": false
-                }
+                "source_location": "23:8-23:10"
               },
-              "source_location": {
-                "start": {
-                  "line": 23,
-                  "column": 3
-                },
-                "end": {
-                  "line": 23,
-                  "column": 11
-                },
-                "is_synthetic": false
-              }
+              "source_location": "23:3-23:11"
             },
             "type": {
               "array_type": {
@@ -393,265 +114,66 @@
                       "source_name": [
                         {
                           "text": "UInt",
-                          "source_location": {
-                            "start": {
-                              "line": 23,
-                              "column": 13
-                            },
-                            "end": {
-                              "line": 23,
-                              "column": 17
-                            },
-                            "is_synthetic": false
-                          }
+                          "source_location": "23:13-23:17"
                         }
                       ],
-                      "source_location": {
-                        "start": {
-                          "line": 23,
-                          "column": 13
-                        },
-                        "end": {
-                          "line": 23,
-                          "column": 17
-                        },
-                        "is_synthetic": false
-                      }
+                      "source_location": "23:13-23:17"
                     },
-                    "source_location": {
-                      "start": {
-                        "line": 23,
-                        "column": 13
-                      },
-                      "end": {
-                        "line": 23,
-                        "column": 17
-                      },
-                      "is_synthetic": false
-                    }
+                    "source_location": "23:13-23:17"
                   },
                   "size_in_bits": {
                     "constant": {
                       "value": "8",
-                      "source_location": {
-                        "start": {
-                          "line": 23,
-                          "column": 18
-                        },
-                        "end": {
-                          "line": 23,
-                          "column": 19
-                        },
-                        "is_synthetic": false
-                      }
+                      "source_location": "23:18-23:19"
                     },
-                    "source_location": {
-                      "start": {
-                        "line": 23,
-                        "column": 17
-                      },
-                      "end": {
-                        "line": 23,
-                        "column": 19
-                      },
-                      "is_synthetic": false
-                    }
+                    "source_location": "23:17-23:19"
                   },
-                  "source_location": {
-                    "start": {
-                      "line": 23,
-                      "column": 13
-                    },
-                    "end": {
-                      "line": 23,
-                      "column": 19
-                    },
-                    "is_synthetic": false
-                  }
+                  "source_location": "23:13-23:19"
                 },
                 "element_count": {
                   "constant": {
                     "value": "12",
-                    "source_location": {
-                      "start": {
-                        "line": 23,
-                        "column": 20
-                      },
-                      "end": {
-                        "line": 23,
-                        "column": 22
-                      },
-                      "is_synthetic": false
-                    }
+                    "source_location": "23:20-23:22"
                   },
-                  "source_location": {
-                    "start": {
-                      "line": 23,
-                      "column": 19
-                    },
-                    "end": {
-                      "line": 23,
-                      "column": 23
-                    },
-                    "is_synthetic": false
-                  }
+                  "source_location": "23:19-23:23"
                 },
-                "source_location": {
-                  "start": {
-                    "line": 23,
-                    "column": 13
-                  },
-                  "end": {
-                    "line": 23,
-                    "column": 23
-                  },
-                  "is_synthetic": false
-                }
+                "source_location": "23:13-23:23"
               },
-              "source_location": {
-                "start": {
-                  "line": 23,
-                  "column": 13
-                },
-                "end": {
-                  "line": 23,
-                  "column": 23
-                },
-                "is_synthetic": false
-              }
+              "source_location": "23:13-23:23"
             },
             "name": {
               "name": {
                 "text": "file_name",
-                "source_location": {
-                  "start": {
-                    "line": 23,
-                    "column": 25
-                  },
-                  "end": {
-                    "line": 23,
-                    "column": 34
-                  },
-                  "is_synthetic": false
-                }
+                "source_location": "23:25-23:34"
               },
-              "source_location": {
-                "start": {
-                  "line": 23,
-                  "column": 25
-                },
-                "end": {
-                  "line": 23,
-                  "column": 34
-                },
-                "is_synthetic": false
-              }
-            },
-            "source_location": {
-              "start": {
-                "line": 23,
-                "column": 3
-              },
-              "end": {
-                "line": 23,
-                "column": 34
-              }
+              "source_location": "23:25-23:34"
             },
             "existence_condition": {
-              "source_location": {
-                "start": {
-                  "line": 23,
-                  "column": 3
-                },
-                "end": {
-                  "line": 23,
-                  "column": 34
-                },
-                "is_synthetic": false
-              },
               "boolean_constant": {
-                "source_location": {
-                  "start": {
-                    "line": 23,
-                    "column": 3
-                  },
-                  "end": {
-                    "line": 23,
-                    "column": 34
-                  },
-                  "is_synthetic": false
-                },
-                "value": true
-              }
-            }
+                "value": true,
+                "source_location": "23:3-23:34"
+              },
+              "source_location": "23:3-23:34"
+            },
+            "source_location": "23:3-23:34"
           },
           {
             "location": {
               "start": {
                 "constant": {
                   "value": "16",
-                  "source_location": {
-                    "start": {
-                      "line": 24,
-                      "column": 3
-                    },
-                    "end": {
-                      "line": 24,
-                      "column": 5
-                    },
-                    "is_synthetic": false
-                  }
+                  "source_location": "24:3-24:5"
                 },
-                "source_location": {
-                  "start": {
-                    "line": 24,
-                    "column": 3
-                  },
-                  "end": {
-                    "line": 24,
-                    "column": 5
-                  },
-                  "is_synthetic": false
-                }
+                "source_location": "24:3-24:5"
               },
               "size": {
                 "constant": {
                   "value": "4",
-                  "source_location": {
-                    "start": {
-                      "line": 24,
-                      "column": 8
-                    },
-                    "end": {
-                      "line": 24,
-                      "column": 9
-                    },
-                    "is_synthetic": false
-                  }
+                  "source_location": "24:8-24:9"
                 },
-                "source_location": {
-                  "start": {
-                    "line": 24,
-                    "column": 8
-                  },
-                  "end": {
-                    "line": 24,
-                    "column": 9
-                  },
-                  "is_synthetic": false
-                }
+                "source_location": "24:8-24:9"
               },
-              "source_location": {
-                "start": {
-                  "line": 24,
-                  "column": 3
-                },
-                "end": {
-                  "line": 24,
-                  "column": 10
-                },
-                "is_synthetic": false
-              }
+              "source_location": "24:3-24:10"
             },
             "type": {
               "atomic_type": {
@@ -659,187 +181,48 @@
                   "source_name": [
                     {
                       "text": "UInt",
-                      "source_location": {
-                        "start": {
-                          "line": 24,
-                          "column": 13
-                        },
-                        "end": {
-                          "line": 24,
-                          "column": 17
-                        },
-                        "is_synthetic": false
-                      }
+                      "source_location": "24:13-24:17"
                     }
                   ],
-                  "source_location": {
-                    "start": {
-                      "line": 24,
-                      "column": 13
-                    },
-                    "end": {
-                      "line": 24,
-                      "column": 17
-                    },
-                    "is_synthetic": false
-                  }
+                  "source_location": "24:13-24:17"
                 },
-                "source_location": {
-                  "start": {
-                    "line": 24,
-                    "column": 13
-                  },
-                  "end": {
-                    "line": 24,
-                    "column": 17
-                  },
-                  "is_synthetic": false
-                }
+                "source_location": "24:13-24:17"
               },
-              "source_location": {
-                "start": {
-                  "line": 24,
-                  "column": 13
-                },
-                "end": {
-                  "line": 24,
-                  "column": 17
-                },
-                "is_synthetic": false
-              }
+              "source_location": "24:13-24:17"
             },
             "name": {
               "name": {
                 "text": "file_size_kb",
-                "source_location": {
-                  "start": {
-                    "line": 24,
-                    "column": 25
-                  },
-                  "end": {
-                    "line": 24,
-                    "column": 37
-                  },
-                  "is_synthetic": false
-                }
+                "source_location": "24:25-24:37"
               },
-              "source_location": {
-                "start": {
-                  "line": 24,
-                  "column": 25
-                },
-                "end": {
-                  "line": 24,
-                  "column": 37
-                },
-                "is_synthetic": false
-              }
-            },
-            "source_location": {
-              "start": {
-                "line": 24,
-                "column": 3
-              },
-              "end": {
-                "line": 24,
-                "column": 37
-              }
+              "source_location": "24:25-24:37"
             },
             "existence_condition": {
-              "source_location": {
-                "start": {
-                  "line": 24,
-                  "column": 3
-                },
-                "end": {
-                  "line": 24,
-                  "column": 37
-                },
-                "is_synthetic": false
-              },
               "boolean_constant": {
-                "source_location": {
-                  "start": {
-                    "line": 24,
-                    "column": 3
-                  },
-                  "end": {
-                    "line": 24,
-                    "column": 37
-                  },
-                  "is_synthetic": false
-                },
-                "value": true
-              }
-            }
+                "value": true,
+                "source_location": "24:3-24:37"
+              },
+              "source_location": "24:3-24:37"
+            },
+            "source_location": "24:3-24:37"
           },
           {
             "location": {
               "start": {
                 "constant": {
                   "value": "20",
-                  "source_location": {
-                    "start": {
-                      "line": 25,
-                      "column": 3
-                    },
-                    "end": {
-                      "line": 25,
-                      "column": 5
-                    },
-                    "is_synthetic": false
-                  }
+                  "source_location": "25:3-25:5"
                 },
-                "source_location": {
-                  "start": {
-                    "line": 25,
-                    "column": 3
-                  },
-                  "end": {
-                    "line": 25,
-                    "column": 5
-                  },
-                  "is_synthetic": false
-                }
+                "source_location": "25:3-25:5"
               },
               "size": {
                 "constant": {
                   "value": "4",
-                  "source_location": {
-                    "start": {
-                      "line": 25,
-                      "column": 8
-                    },
-                    "end": {
-                      "line": 25,
-                      "column": 9
-                    },
-                    "is_synthetic": false
-                  }
+                  "source_location": "25:8-25:9"
                 },
-                "source_location": {
-                  "start": {
-                    "line": 25,
-                    "column": 8
-                  },
-                  "end": {
-                    "line": 25,
-                    "column": 9
-                  },
-                  "is_synthetic": false
-                }
+                "source_location": "25:8-25:9"
               },
-              "source_location": {
-                "start": {
-                  "line": 25,
-                  "column": 3
-                },
-                "end": {
-                  "line": 25,
-                  "column": 10
-                },
-                "is_synthetic": false
-              }
+              "source_location": "25:3-25:10"
             },
             "type": {
               "atomic_type": {
@@ -847,242 +230,64 @@
                   "source_name": [
                     {
                       "text": "UInt",
-                      "source_location": {
-                        "start": {
-                          "line": 25,
-                          "column": 13
-                        },
-                        "end": {
-                          "line": 25,
-                          "column": 17
-                        },
-                        "is_synthetic": false
-                      }
+                      "source_location": "25:13-25:17"
                     }
                   ],
-                  "source_location": {
-                    "start": {
-                      "line": 25,
-                      "column": 13
-                    },
-                    "end": {
-                      "line": 25,
-                      "column": 17
-                    },
-                    "is_synthetic": false
-                  }
+                  "source_location": "25:13-25:17"
                 },
-                "source_location": {
-                  "start": {
-                    "line": 25,
-                    "column": 13
-                  },
-                  "end": {
-                    "line": 25,
-                    "column": 17
-                  },
-                  "is_synthetic": false
-                }
+                "source_location": "25:13-25:17"
               },
-              "source_location": {
-                "start": {
-                  "line": 25,
-                  "column": 13
-                },
-                "end": {
-                  "line": 25,
-                  "column": 17
-                },
-                "is_synthetic": false
-              }
+              "source_location": "25:13-25:17"
             },
             "name": {
               "name": {
                 "text": "media",
-                "source_location": {
-                  "start": {
-                    "line": 25,
-                    "column": 25
-                  },
-                  "end": {
-                    "line": 25,
-                    "column": 30
-                  },
-                  "is_synthetic": false
-                }
+                "source_location": "25:25-25:30"
               },
-              "source_location": {
-                "start": {
-                  "line": 25,
-                  "column": 25
-                },
-                "end": {
-                  "line": 25,
-                  "column": 30
-                },
-                "is_synthetic": false
-              }
-            },
-            "source_location": {
-              "start": {
-                "line": 25,
-                "column": 3
-              },
-              "end": {
-                "line": 25,
-                "column": 30
-              }
+              "source_location": "25:25-25:30"
             },
             "existence_condition": {
-              "source_location": {
-                "start": {
-                  "line": 25,
-                  "column": 3
-                },
-                "end": {
-                  "line": 25,
-                  "column": 30
-                },
-                "is_synthetic": false
-              },
               "boolean_constant": {
-                "source_location": {
-                  "start": {
-                    "line": 25,
-                    "column": 3
-                  },
-                  "end": {
-                    "line": 25,
-                    "column": 30
-                  },
-                  "is_synthetic": false
-                },
-                "value": true
-              }
-            }
+                "value": true,
+                "source_location": "25:3-25:30"
+              },
+              "source_location": "25:3-25:30"
+            },
+            "source_location": "25:3-25:30"
           }
         ],
-        "source_location": {
-          "start": {
-            "line": 21,
-            "column": 1
-          },
-          "end": {
-            "line": 26,
-            "column": 1
-          }
-        }
-      },
-      "addressable_unit": 8,
-      "source_location": {
-        "start": {
-          "line": 21,
-          "column": 1
-        },
-        "end": {
-          "line": 26,
-          "column": 1
-        },
-        "is_synthetic": false
+        "source_location": "21:1-26:1"
       },
       "name": {
         "name": {
           "text": "LogFileStatus",
-          "source_location": {
-            "start": {
-              "line": 21,
-              "column": 8
-            },
-            "end": {
-              "line": 21,
-              "column": 21
-            },
-            "is_synthetic": false
-          }
+          "source_location": "21:8-21:21"
         },
-        "source_location": {
-          "start": {
-            "line": 21,
-            "column": 8
-          },
-          "end": {
-            "line": 21,
-            "column": 21
-          },
-          "is_synthetic": false
-        }
-      }
+        "source_location": "21:8-21:21"
+      },
+      "addressable_unit": 8,
+      "source_location": "21:1-26:1"
     }
   ],
   "documentation": [
     {
       "text": "This is a simple, real-world example structure.",
-      "source_location": {
-        "start": {
-          "line": 15,
-          "column": 1
-        },
-        "end": {
-          "line": 16,
-          "column": 1
-        },
-        "is_synthetic": false
-      }
+      "source_location": "15:1-16:1"
     }
   ],
   "foreign_import": [
     {
       "file_name": {
         "text": "",
-        "source_location": {
-          "start": {
-            "line": 16,
-            "column": 1
-          },
-          "end": {
-            "line": 16,
-            "column": 1
-          },
-          "is_synthetic": false
-        }
+        "source_location": "16:1-16:1"
       },
       "local_name": {
         "text": "",
-        "source_location": {
-          "start": {
-            "line": 16,
-            "column": 1
-          },
-          "end": {
-            "line": 16,
-            "column": 1
-          },
-          "is_synthetic": false
-        }
+        "source_location": "16:1-16:1"
       },
-      "source_location": {
-        "start": {
-          "line": 16,
-          "column": 1
-        },
-        "end": {
-          "line": 16,
-          "column": 1
-        },
-        "is_synthetic": false
-      }
+      "source_location": "16:1-16:1"
     }
   ],
-  "source_location": {
-    "start": {
-      "line": 1,
-      "column": 1
-    },
-    "end": {
-      "line": 26,
-      "column": 1
-    },
-    "is_synthetic": false
-  },
-  "source_text": "# Copyright 2019 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n-- This is a simple, real-world example structure.\n\n[$default byte_order: \"LittleEndian\"]\n[(cpp) namespace: \"emboss::test\"]\n\n\nstruct LogFileStatus:\n  0  [+4]   UInt        file_state\n  4  [+12]  UInt:8[12]  file_name\n  16 [+4]   UInt        file_size_kb\n  20 [+4]   UInt        media\n"
+  "source_text": "# Copyright 2019 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n-- This is a simple, real-world example structure.\n\n[$default byte_order: \"LittleEndian\"]\n[(cpp) namespace: \"emboss::test\"]\n\n\nstruct LogFileStatus:\n  0  [+4]   UInt        file_state\n  4  [+12]  UInt:8[12]  file_name\n  16 [+4]   UInt        file_size_kb\n  20 [+4]   UInt        media\n",
+  "source_location": "1:1-26:1"
 }
diff --git a/testdata/golden/span_se_log_file_status.parse_tree.txt b/testdata/golden/span_se_log_file_status.parse_tree.txt
index bd15bdd..e415367 100644
--- a/testdata/golden/span_se_log_file_status.parse_tree.txt
+++ b/testdata/golden/span_se_log_file_status.parse_tree.txt
@@ -3,67 +3,67 @@
     comment-line:
       Comment?:
         Comment '# Copyright 2019 Google LLC' 1:1-1:28
-      "\n" '\n' 1:1-1:28
+      "\n" '\n' 1:28-1:28
     comment-line*:
       comment-line:
         Comment?:
           Comment '#' 2:1-2:2
-        "\n" '\n' 2:1-2:2
+        "\n" '\n' 2:2-2:2
       comment-line*:
         comment-line:
           Comment?:
             Comment '# Licensed under the Apache License, Version 2.0 (the "License");' 3:1-3:66
-          "\n" '\n' 3:1-3:66
+          "\n" '\n' 3:66-3:66
         comment-line*:
           comment-line:
             Comment?:
               Comment '# you may not use this file except in compliance with the License.' 4:1-4:67
-            "\n" '\n' 4:1-4:67
+            "\n" '\n' 4:67-4:67
           comment-line*:
             comment-line:
               Comment?:
                 Comment '# You may obtain a copy of the License at' 5:1-5:42
-              "\n" '\n' 5:1-5:42
+              "\n" '\n' 5:42-5:42
             comment-line*:
               comment-line:
                 Comment?:
                   Comment '#' 6:1-6:2
-                "\n" '\n' 6:1-6:2
+                "\n" '\n' 6:2-6:2
               comment-line*:
                 comment-line:
                   Comment?:
                     Comment '#     https://www.apache.org/licenses/LICENSE-2.0' 7:1-7:50
-                  "\n" '\n' 7:1-7:50
+                  "\n" '\n' 7:50-7:50
                 comment-line*:
                   comment-line:
                     Comment?:
                       Comment '#' 8:1-8:2
-                    "\n" '\n' 8:1-8:2
+                    "\n" '\n' 8:2-8:2
                   comment-line*:
                     comment-line:
                       Comment?:
                         Comment '# Unless required by applicable law or agreed to in writing, software' 9:1-9:70
-                      "\n" '\n' 9:1-9:70
+                      "\n" '\n' 9:70-9:70
                     comment-line*:
                       comment-line:
                         Comment?:
                           Comment '# distributed under the License is distributed on an "AS IS" BASIS,' 10:1-10:68
-                        "\n" '\n' 10:1-10:68
+                        "\n" '\n' 10:68-10:68
                       comment-line*:
                         comment-line:
                           Comment?:
                             Comment '# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.' 11:1-11:75
-                          "\n" '\n' 11:1-11:75
+                          "\n" '\n' 11:75-11:75
                         comment-line*:
                           comment-line:
                             Comment?:
                               Comment '# See the License for the specific language governing permissions and' 12:1-12:70
-                            "\n" '\n' 12:1-12:70
+                            "\n" '\n' 12:70-12:70
                           comment-line*:
                             comment-line:
                               Comment?:
                                 Comment '# limitations under the License.' 13:1-13:33
-                              "\n" '\n' 13:1-13:33
+                              "\n" '\n' 13:33-13:33
                             comment-line*:
                               comment-line:
                                 Comment?
@@ -75,7 +75,7 @@
         Documentation '-- This is a simple, real-world example structure.' 15:1-15:51
       Comment?
       eol:
-        "\n" '\n' 15:51-16:1
+        "\n" '\n' 15:51-15:51
         comment-line*:
           comment-line:
             Comment?
@@ -121,7 +121,7 @@
           "]" ']' 18:33-18:34
         Comment?
         eol:
-          "\n" '\n' 18:34-20:1
+          "\n" '\n' 18:34-18:34
           comment-line*:
             comment-line:
               Comment?
diff --git a/testdata/golden/span_se_log_file_status.tokens.txt b/testdata/golden/span_se_log_file_status.tokens.txt
index 5474c99..91937f0 100644
--- a/testdata/golden/span_se_log_file_status.tokens.txt
+++ b/testdata/golden/span_se_log_file_status.tokens.txt
@@ -1,32 +1,32 @@
 Comment '# Copyright 2019 Google LLC' 1:1-1:28
-"\n" '\n' 1:1-1:28
+"\n" '\n' 1:28-1:28
 Comment '#' 2:1-2:2
-"\n" '\n' 2:1-2:2
+"\n" '\n' 2:2-2:2
 Comment '# Licensed under the Apache License, Version 2.0 (the "License");' 3:1-3:66
-"\n" '\n' 3:1-3:66
+"\n" '\n' 3:66-3:66
 Comment '# you may not use this file except in compliance with the License.' 4:1-4:67
-"\n" '\n' 4:1-4:67
+"\n" '\n' 4:67-4:67
 Comment '# You may obtain a copy of the License at' 5:1-5:42
-"\n" '\n' 5:1-5:42
+"\n" '\n' 5:42-5:42
 Comment '#' 6:1-6:2
-"\n" '\n' 6:1-6:2
+"\n" '\n' 6:2-6:2
 Comment '#     https://www.apache.org/licenses/LICENSE-2.0' 7:1-7:50
-"\n" '\n' 7:1-7:50
+"\n" '\n' 7:50-7:50
 Comment '#' 8:1-8:2
-"\n" '\n' 8:1-8:2
+"\n" '\n' 8:2-8:2
 Comment '# Unless required by applicable law or agreed to in writing, software' 9:1-9:70
-"\n" '\n' 9:1-9:70
+"\n" '\n' 9:70-9:70
 Comment '# distributed under the License is distributed on an "AS IS" BASIS,' 10:1-10:68
-"\n" '\n' 10:1-10:68
+"\n" '\n' 10:68-10:68
 Comment '# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.' 11:1-11:75
-"\n" '\n' 11:1-11:75
+"\n" '\n' 11:75-11:75
 Comment '# See the License for the specific language governing permissions and' 12:1-12:70
-"\n" '\n' 12:1-12:70
+"\n" '\n' 12:70-12:70
 Comment '# limitations under the License.' 13:1-13:33
-"\n" '\n' 13:1-13:33
+"\n" '\n' 13:33-13:33
 "\n" '\n' 14:1-14:1
 Documentation '-- This is a simple, real-world example structure.' 15:1-15:51
-"\n" '\n' 15:51-16:1
+"\n" '\n' 15:51-15:51
 "\n" '\n' 16:1-16:1
 "[" '[' 17:1-17:2
 "$default" '$default' 17:2-17:10
@@ -43,7 +43,7 @@
 ":" ':' 18:17-18:18
 String '"emboss::test"' 18:19-18:33
 "]" ']' 18:33-18:34
-"\n" '\n' 18:34-20:1
+"\n" '\n' 18:34-18:34
 "\n" '\n' 19:1-19:1
 "\n" '\n' 20:1-20:1
 "struct" 'struct' 21:1-21:7
diff --git a/testdata/golden_cpp/BUILD b/testdata/golden_cpp/BUILD
new file mode 100644
index 0000000..d1f63ca
--- /dev/null
+++ b/testdata/golden_cpp/BUILD
@@ -0,0 +1,18 @@
+# Copyright 2025 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+exports_files(
+    glob(["*.emb.h"]),
+    visibility = ["//compiler/back_end/cpp:__pkg__"],
+)
diff --git a/testdata/golden_cpp/absolute_cpp_namespace.emb.h b/testdata/golden_cpp/absolute_cpp_namespace.emb.h
new file mode 100644
index 0000000..fb13bb1
--- /dev/null
+++ b/testdata/golden_cpp/absolute_cpp_namespace.emb.h
@@ -0,0 +1,126 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_ABSOLUTE_CPP_NAMESPACE_EMB_H_
+#define TESTDATA_ABSOLUTE_CPP_NAMESPACE_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace leading_double_colon {
+enum class Foo : ::std::uint64_t;
+
+
+enum class Foo : ::std::uint64_t {
+  VALUE = static_cast</**/::std::int32_t>(12LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<Foo> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   Foo *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("VALUE", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Foo::VALUE;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      Foo emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Foo::VALUE: return "VALUE";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(Foo emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Foo::VALUE: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       Foo emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<Foo>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    Foo *emboss_reserved_local_result) {
+  return EnumTraits<Foo>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    Foo emboss_reserved_local_value) {
+  return EnumTraits<Foo>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(Foo emboss_reserved_local_value) {
+  return EnumTraits<Foo>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    Foo emboss_reserved_local_value) {
+  return EnumTraits<Foo>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+
+
+
+
+}  // namespace leading_double_colon
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_ABSOLUTE_CPP_NAMESPACE_EMB_H_
+
diff --git a/testdata/golden_cpp/alignments.emb.h b/testdata/golden_cpp/alignments.emb.h
new file mode 100644
index 0000000..e60daf5
--- /dev/null
+++ b/testdata/golden_cpp/alignments.emb.h
@@ -0,0 +1,2953 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_ALIGNMENTS_EMB_H_
+#define TESTDATA_ALIGNMENTS_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace Alignments {
+
+}  // namespace Alignments
+
+
+template <class Storage>
+class GenericAlignmentsView;
+
+namespace Placeholder4 {
+
+}  // namespace Placeholder4
+
+
+template <class Storage>
+class GenericPlaceholder4View;
+
+namespace Placeholder6 {
+
+}  // namespace Placeholder6
+
+
+template <class Storage>
+class GenericPlaceholder6View;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+namespace Alignments {
+
+}  // namespace Alignments
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericAlignmentsView;
+
+template <class Storage>
+class GenericAlignmentsView final {
+ public:
+  GenericAlignmentsView() : backing_() {}
+  explicit GenericAlignmentsView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericAlignmentsView(
+      const GenericAlignmentsView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericAlignmentsView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericAlignmentsView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericAlignmentsView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericAlignmentsView<Storage> &operator=(
+      const GenericAlignmentsView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_zero_offset().Known()) return false;
+    if (has_zero_offset().ValueOrDefault() && !zero_offset().Ok()) return false;
+
+
+    if (!has_zero_offset_substructure().Known()) return false;
+    if (has_zero_offset_substructure().ValueOrDefault() && !zero_offset_substructure().Ok()) return false;
+
+
+    if (!has_two_offset_substructure().Known()) return false;
+    if (has_two_offset_substructure().ValueOrDefault() && !two_offset_substructure().Ok()) return false;
+
+
+    if (!has_three_offset().Known()) return false;
+    if (has_three_offset().ValueOrDefault() && !three_offset().Ok()) return false;
+
+
+    if (!has_four_offset().Known()) return false;
+    if (has_four_offset().ValueOrDefault() && !four_offset().Ok()) return false;
+
+
+    if (!has_eleven_offset().Known()) return false;
+    if (has_eleven_offset().ValueOrDefault() && !eleven_offset().Ok()) return false;
+
+
+    if (!has_twelve_offset().Known()) return false;
+    if (has_twelve_offset().ValueOrDefault() && !twelve_offset().Ok()) return false;
+
+
+    if (!has_zero_offset_four_stride_array().Known()) return false;
+    if (has_zero_offset_four_stride_array().ValueOrDefault() && !zero_offset_four_stride_array().Ok()) return false;
+
+
+    if (!has_zero_offset_six_stride_array().Known()) return false;
+    if (has_zero_offset_six_stride_array().ValueOrDefault() && !zero_offset_six_stride_array().Ok()) return false;
+
+
+    if (!has_three_offset_four_stride_array().Known()) return false;
+    if (has_three_offset_four_stride_array().ValueOrDefault() && !three_offset_four_stride_array().Ok()) return false;
+
+
+    if (!has_four_offset_six_stride_array().Known()) return false;
+    if (has_four_offset_six_stride_array().ValueOrDefault() && !four_offset_six_stride_array().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericAlignmentsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_zero_offset().Known()) return false;
+    if (!emboss_reserved_local_other.has_zero_offset().Known()) return false;
+
+    if (emboss_reserved_local_other.has_zero_offset().ValueOrDefault() &&
+        !has_zero_offset().ValueOrDefault())
+      return false;
+    if (has_zero_offset().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_zero_offset().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_zero_offset().ValueOrDefault() &&
+        has_zero_offset().ValueOrDefault() &&
+        !zero_offset().Equals(emboss_reserved_local_other.zero_offset()))
+      return false;
+
+
+
+    if (!has_zero_offset_substructure().Known()) return false;
+    if (!emboss_reserved_local_other.has_zero_offset_substructure().Known()) return false;
+
+    if (emboss_reserved_local_other.has_zero_offset_substructure().ValueOrDefault() &&
+        !has_zero_offset_substructure().ValueOrDefault())
+      return false;
+    if (has_zero_offset_substructure().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_zero_offset_substructure().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_zero_offset_substructure().ValueOrDefault() &&
+        has_zero_offset_substructure().ValueOrDefault() &&
+        !zero_offset_substructure().Equals(emboss_reserved_local_other.zero_offset_substructure()))
+      return false;
+
+
+
+    if (!has_two_offset_substructure().Known()) return false;
+    if (!emboss_reserved_local_other.has_two_offset_substructure().Known()) return false;
+
+    if (emboss_reserved_local_other.has_two_offset_substructure().ValueOrDefault() &&
+        !has_two_offset_substructure().ValueOrDefault())
+      return false;
+    if (has_two_offset_substructure().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_two_offset_substructure().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_two_offset_substructure().ValueOrDefault() &&
+        has_two_offset_substructure().ValueOrDefault() &&
+        !two_offset_substructure().Equals(emboss_reserved_local_other.two_offset_substructure()))
+      return false;
+
+
+
+    if (!has_three_offset().Known()) return false;
+    if (!emboss_reserved_local_other.has_three_offset().Known()) return false;
+
+    if (emboss_reserved_local_other.has_three_offset().ValueOrDefault() &&
+        !has_three_offset().ValueOrDefault())
+      return false;
+    if (has_three_offset().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_three_offset().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_three_offset().ValueOrDefault() &&
+        has_three_offset().ValueOrDefault() &&
+        !three_offset().Equals(emboss_reserved_local_other.three_offset()))
+      return false;
+
+
+
+    if (!has_four_offset().Known()) return false;
+    if (!emboss_reserved_local_other.has_four_offset().Known()) return false;
+
+    if (emboss_reserved_local_other.has_four_offset().ValueOrDefault() &&
+        !has_four_offset().ValueOrDefault())
+      return false;
+    if (has_four_offset().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_four_offset().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_four_offset().ValueOrDefault() &&
+        has_four_offset().ValueOrDefault() &&
+        !four_offset().Equals(emboss_reserved_local_other.four_offset()))
+      return false;
+
+
+
+    if (!has_eleven_offset().Known()) return false;
+    if (!emboss_reserved_local_other.has_eleven_offset().Known()) return false;
+
+    if (emboss_reserved_local_other.has_eleven_offset().ValueOrDefault() &&
+        !has_eleven_offset().ValueOrDefault())
+      return false;
+    if (has_eleven_offset().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_eleven_offset().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_eleven_offset().ValueOrDefault() &&
+        has_eleven_offset().ValueOrDefault() &&
+        !eleven_offset().Equals(emboss_reserved_local_other.eleven_offset()))
+      return false;
+
+
+
+    if (!has_twelve_offset().Known()) return false;
+    if (!emboss_reserved_local_other.has_twelve_offset().Known()) return false;
+
+    if (emboss_reserved_local_other.has_twelve_offset().ValueOrDefault() &&
+        !has_twelve_offset().ValueOrDefault())
+      return false;
+    if (has_twelve_offset().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_twelve_offset().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_twelve_offset().ValueOrDefault() &&
+        has_twelve_offset().ValueOrDefault() &&
+        !twelve_offset().Equals(emboss_reserved_local_other.twelve_offset()))
+      return false;
+
+
+
+    if (!has_zero_offset_four_stride_array().Known()) return false;
+    if (!emboss_reserved_local_other.has_zero_offset_four_stride_array().Known()) return false;
+
+    if (emboss_reserved_local_other.has_zero_offset_four_stride_array().ValueOrDefault() &&
+        !has_zero_offset_four_stride_array().ValueOrDefault())
+      return false;
+    if (has_zero_offset_four_stride_array().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_zero_offset_four_stride_array().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_zero_offset_four_stride_array().ValueOrDefault() &&
+        has_zero_offset_four_stride_array().ValueOrDefault() &&
+        !zero_offset_four_stride_array().Equals(emboss_reserved_local_other.zero_offset_four_stride_array()))
+      return false;
+
+
+
+    if (!has_zero_offset_six_stride_array().Known()) return false;
+    if (!emboss_reserved_local_other.has_zero_offset_six_stride_array().Known()) return false;
+
+    if (emboss_reserved_local_other.has_zero_offset_six_stride_array().ValueOrDefault() &&
+        !has_zero_offset_six_stride_array().ValueOrDefault())
+      return false;
+    if (has_zero_offset_six_stride_array().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_zero_offset_six_stride_array().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_zero_offset_six_stride_array().ValueOrDefault() &&
+        has_zero_offset_six_stride_array().ValueOrDefault() &&
+        !zero_offset_six_stride_array().Equals(emboss_reserved_local_other.zero_offset_six_stride_array()))
+      return false;
+
+
+
+    if (!has_three_offset_four_stride_array().Known()) return false;
+    if (!emboss_reserved_local_other.has_three_offset_four_stride_array().Known()) return false;
+
+    if (emboss_reserved_local_other.has_three_offset_four_stride_array().ValueOrDefault() &&
+        !has_three_offset_four_stride_array().ValueOrDefault())
+      return false;
+    if (has_three_offset_four_stride_array().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_three_offset_four_stride_array().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_three_offset_four_stride_array().ValueOrDefault() &&
+        has_three_offset_four_stride_array().ValueOrDefault() &&
+        !three_offset_four_stride_array().Equals(emboss_reserved_local_other.three_offset_four_stride_array()))
+      return false;
+
+
+
+    if (!has_four_offset_six_stride_array().Known()) return false;
+    if (!emboss_reserved_local_other.has_four_offset_six_stride_array().Known()) return false;
+
+    if (emboss_reserved_local_other.has_four_offset_six_stride_array().ValueOrDefault() &&
+        !has_four_offset_six_stride_array().ValueOrDefault())
+      return false;
+    if (has_four_offset_six_stride_array().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_four_offset_six_stride_array().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_four_offset_six_stride_array().ValueOrDefault() &&
+        has_four_offset_six_stride_array().ValueOrDefault() &&
+        !four_offset_six_stride_array().Equals(emboss_reserved_local_other.four_offset_six_stride_array()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericAlignmentsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_zero_offset().ValueOr(false) &&
+        !has_zero_offset().ValueOr(false))
+      return false;
+    if (has_zero_offset().ValueOr(false) &&
+        !emboss_reserved_local_other.has_zero_offset().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_zero_offset().ValueOr(false) &&
+        has_zero_offset().ValueOr(false) &&
+        !zero_offset().UncheckedEquals(emboss_reserved_local_other.zero_offset()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_zero_offset_substructure().ValueOr(false) &&
+        !has_zero_offset_substructure().ValueOr(false))
+      return false;
+    if (has_zero_offset_substructure().ValueOr(false) &&
+        !emboss_reserved_local_other.has_zero_offset_substructure().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_zero_offset_substructure().ValueOr(false) &&
+        has_zero_offset_substructure().ValueOr(false) &&
+        !zero_offset_substructure().UncheckedEquals(emboss_reserved_local_other.zero_offset_substructure()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_two_offset_substructure().ValueOr(false) &&
+        !has_two_offset_substructure().ValueOr(false))
+      return false;
+    if (has_two_offset_substructure().ValueOr(false) &&
+        !emboss_reserved_local_other.has_two_offset_substructure().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_two_offset_substructure().ValueOr(false) &&
+        has_two_offset_substructure().ValueOr(false) &&
+        !two_offset_substructure().UncheckedEquals(emboss_reserved_local_other.two_offset_substructure()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_three_offset().ValueOr(false) &&
+        !has_three_offset().ValueOr(false))
+      return false;
+    if (has_three_offset().ValueOr(false) &&
+        !emboss_reserved_local_other.has_three_offset().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_three_offset().ValueOr(false) &&
+        has_three_offset().ValueOr(false) &&
+        !three_offset().UncheckedEquals(emboss_reserved_local_other.three_offset()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_four_offset().ValueOr(false) &&
+        !has_four_offset().ValueOr(false))
+      return false;
+    if (has_four_offset().ValueOr(false) &&
+        !emboss_reserved_local_other.has_four_offset().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_four_offset().ValueOr(false) &&
+        has_four_offset().ValueOr(false) &&
+        !four_offset().UncheckedEquals(emboss_reserved_local_other.four_offset()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_eleven_offset().ValueOr(false) &&
+        !has_eleven_offset().ValueOr(false))
+      return false;
+    if (has_eleven_offset().ValueOr(false) &&
+        !emboss_reserved_local_other.has_eleven_offset().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_eleven_offset().ValueOr(false) &&
+        has_eleven_offset().ValueOr(false) &&
+        !eleven_offset().UncheckedEquals(emboss_reserved_local_other.eleven_offset()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_twelve_offset().ValueOr(false) &&
+        !has_twelve_offset().ValueOr(false))
+      return false;
+    if (has_twelve_offset().ValueOr(false) &&
+        !emboss_reserved_local_other.has_twelve_offset().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_twelve_offset().ValueOr(false) &&
+        has_twelve_offset().ValueOr(false) &&
+        !twelve_offset().UncheckedEquals(emboss_reserved_local_other.twelve_offset()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_zero_offset_four_stride_array().ValueOr(false) &&
+        !has_zero_offset_four_stride_array().ValueOr(false))
+      return false;
+    if (has_zero_offset_four_stride_array().ValueOr(false) &&
+        !emboss_reserved_local_other.has_zero_offset_four_stride_array().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_zero_offset_four_stride_array().ValueOr(false) &&
+        has_zero_offset_four_stride_array().ValueOr(false) &&
+        !zero_offset_four_stride_array().UncheckedEquals(emboss_reserved_local_other.zero_offset_four_stride_array()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_zero_offset_six_stride_array().ValueOr(false) &&
+        !has_zero_offset_six_stride_array().ValueOr(false))
+      return false;
+    if (has_zero_offset_six_stride_array().ValueOr(false) &&
+        !emboss_reserved_local_other.has_zero_offset_six_stride_array().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_zero_offset_six_stride_array().ValueOr(false) &&
+        has_zero_offset_six_stride_array().ValueOr(false) &&
+        !zero_offset_six_stride_array().UncheckedEquals(emboss_reserved_local_other.zero_offset_six_stride_array()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_three_offset_four_stride_array().ValueOr(false) &&
+        !has_three_offset_four_stride_array().ValueOr(false))
+      return false;
+    if (has_three_offset_four_stride_array().ValueOr(false) &&
+        !emboss_reserved_local_other.has_three_offset_four_stride_array().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_three_offset_four_stride_array().ValueOr(false) &&
+        has_three_offset_four_stride_array().ValueOr(false) &&
+        !three_offset_four_stride_array().UncheckedEquals(emboss_reserved_local_other.three_offset_four_stride_array()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_four_offset_six_stride_array().ValueOr(false) &&
+        !has_four_offset_six_stride_array().ValueOr(false))
+      return false;
+    if (has_four_offset_six_stride_array().ValueOr(false) &&
+        !emboss_reserved_local_other.has_four_offset_six_stride_array().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_four_offset_six_stride_array().ValueOr(false) &&
+        has_four_offset_six_stride_array().ValueOr(false) &&
+        !four_offset_six_stride_array().UncheckedEquals(emboss_reserved_local_other.four_offset_six_stride_array()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericAlignmentsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericAlignmentsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericAlignmentsView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "zero_offset") {
+        if (!zero_offset().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "zero_offset_substructure") {
+        if (!zero_offset_substructure().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "two_offset_substructure") {
+        if (!two_offset_substructure().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "three_offset") {
+        if (!three_offset().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "four_offset") {
+        if (!four_offset().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "eleven_offset") {
+        if (!eleven_offset().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "twelve_offset") {
+        if (!twelve_offset().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "zero_offset_four_stride_array") {
+        if (!zero_offset_four_stride_array().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "zero_offset_six_stride_array") {
+        if (!zero_offset_six_stride_array().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "three_offset_four_stride_array") {
+        if (!three_offset_four_stride_array().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "four_offset_six_stride_array") {
+        if (!four_offset_six_stride_array().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_zero_offset().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          zero_offset().IsAggregate() || zero_offset().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("zero_offset: ");
+        zero_offset().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !zero_offset().IsAggregate() && !zero_offset().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# zero_offset: UNREADABLE\n");
+      }
+    }
+
+    if (has_zero_offset_substructure().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          zero_offset_substructure().IsAggregate() || zero_offset_substructure().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("zero_offset_substructure: ");
+        zero_offset_substructure().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !zero_offset_substructure().IsAggregate() && !zero_offset_substructure().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# zero_offset_substructure: UNREADABLE\n");
+      }
+    }
+
+    if (has_two_offset_substructure().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          two_offset_substructure().IsAggregate() || two_offset_substructure().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("two_offset_substructure: ");
+        two_offset_substructure().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !two_offset_substructure().IsAggregate() && !two_offset_substructure().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# two_offset_substructure: UNREADABLE\n");
+      }
+    }
+
+    if (has_three_offset().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          three_offset().IsAggregate() || three_offset().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("three_offset: ");
+        three_offset().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !three_offset().IsAggregate() && !three_offset().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# three_offset: UNREADABLE\n");
+      }
+    }
+
+    if (has_four_offset().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          four_offset().IsAggregate() || four_offset().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("four_offset: ");
+        four_offset().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !four_offset().IsAggregate() && !four_offset().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# four_offset: UNREADABLE\n");
+      }
+    }
+
+    if (has_eleven_offset().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          eleven_offset().IsAggregate() || eleven_offset().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("eleven_offset: ");
+        eleven_offset().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !eleven_offset().IsAggregate() && !eleven_offset().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# eleven_offset: UNREADABLE\n");
+      }
+    }
+
+    if (has_twelve_offset().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          twelve_offset().IsAggregate() || twelve_offset().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("twelve_offset: ");
+        twelve_offset().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !twelve_offset().IsAggregate() && !twelve_offset().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# twelve_offset: UNREADABLE\n");
+      }
+    }
+
+    if (has_zero_offset_four_stride_array().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          zero_offset_four_stride_array().IsAggregate() || zero_offset_four_stride_array().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("zero_offset_four_stride_array: ");
+        zero_offset_four_stride_array().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !zero_offset_four_stride_array().IsAggregate() && !zero_offset_four_stride_array().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# zero_offset_four_stride_array: UNREADABLE\n");
+      }
+    }
+
+    if (has_zero_offset_six_stride_array().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          zero_offset_six_stride_array().IsAggregate() || zero_offset_six_stride_array().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("zero_offset_six_stride_array: ");
+        zero_offset_six_stride_array().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !zero_offset_six_stride_array().IsAggregate() && !zero_offset_six_stride_array().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# zero_offset_six_stride_array: UNREADABLE\n");
+      }
+    }
+
+    if (has_three_offset_four_stride_array().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          three_offset_four_stride_array().IsAggregate() || three_offset_four_stride_array().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("three_offset_four_stride_array: ");
+        three_offset_four_stride_array().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !three_offset_four_stride_array().IsAggregate() && !three_offset_four_stride_array().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# three_offset_four_stride_array: UNREADABLE\n");
+      }
+    }
+
+    if (has_four_offset_six_stride_array().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          four_offset_six_stride_array().IsAggregate() || four_offset_six_stride_array().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("four_offset_six_stride_array: ");
+        four_offset_six_stride_array().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !four_offset_six_stride_array().IsAggregate() && !four_offset_six_stride_array().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# four_offset_six_stride_array: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ zero_offset() const;
+  ::emboss::support::Maybe<bool> has_zero_offset() const;
+
+ public:
+  typename ::emboss::test::GenericPlaceholder6View<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ zero_offset_substructure() const;
+  ::emboss::support::Maybe<bool> has_zero_offset_substructure() const;
+
+ public:
+  typename ::emboss::test::GenericPlaceholder6View<typename Storage::template OffsetStorageType</**/0, 2>>
+
+ two_offset_substructure() const;
+  ::emboss::support::Maybe<bool> has_two_offset_substructure() const;
+
+ public:
+  typename ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 3>>
+
+ three_offset() const;
+  ::emboss::support::Maybe<bool> has_three_offset() const;
+
+ public:
+  typename ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 4>>
+
+ four_offset() const;
+  ::emboss::support::Maybe<bool> has_four_offset() const;
+
+ public:
+  typename ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 11>>
+
+ eleven_offset() const;
+  ::emboss::support::Maybe<bool> has_eleven_offset() const;
+
+ public:
+  typename ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 12>>
+
+ twelve_offset() const;
+  ::emboss::support::Maybe<bool> has_twelve_offset() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/4, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 4,
+    8 >
+
+ zero_offset_four_stride_array() const;
+  ::emboss::support::Maybe<bool> has_zero_offset_four_stride_array() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericPlaceholder6View<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/6, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 6,
+    8 >
+
+ zero_offset_six_stride_array() const;
+  ::emboss::support::Maybe<bool> has_zero_offset_six_stride_array() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/4, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 4,
+    8 >
+
+ three_offset_four_stride_array() const;
+  ::emboss::support::Maybe<bool> has_three_offset_four_stride_array() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericPlaceholder6View<typename Storage::template OffsetStorageType</**/0, 4>::template OffsetStorageType</**/6, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 4>, 6,
+    8 >
+
+ four_offset_six_stride_array() const;
+  ::emboss::support::Maybe<bool> has_four_offset_six_stride_array() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericAlignmentsView;
+};
+using AlignmentsView =
+    GenericAlignmentsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using AlignmentsWriter =
+    GenericAlignmentsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericAlignmentsView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericAlignmentsView<
+    GenericAlignmentsView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericAlignmentsView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeAlignmentsView( T &&emboss_reserved_local_arg) {
+  return GenericAlignmentsView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericAlignmentsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeAlignmentsView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericAlignmentsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericAlignmentsView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedAlignmentsView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericAlignmentsView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+namespace Placeholder4 {
+
+}  // namespace Placeholder4
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericPlaceholder4View;
+
+template <class Storage>
+class GenericPlaceholder4View final {
+ public:
+  GenericPlaceholder4View() : backing_() {}
+  explicit GenericPlaceholder4View(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericPlaceholder4View(
+      const GenericPlaceholder4View<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericPlaceholder4View<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericPlaceholder4View(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericPlaceholder4View(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericPlaceholder4View<Storage> &operator=(
+      const GenericPlaceholder4View<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_dummy().Known()) return false;
+    if (has_dummy().ValueOrDefault() && !dummy().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericPlaceholder4View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_dummy().Known()) return false;
+    if (!emboss_reserved_local_other.has_dummy().Known()) return false;
+
+    if (emboss_reserved_local_other.has_dummy().ValueOrDefault() &&
+        !has_dummy().ValueOrDefault())
+      return false;
+    if (has_dummy().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_dummy().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_dummy().ValueOrDefault() &&
+        has_dummy().ValueOrDefault() &&
+        !dummy().Equals(emboss_reserved_local_other.dummy()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericPlaceholder4View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_dummy().ValueOr(false) &&
+        !has_dummy().ValueOr(false))
+      return false;
+    if (has_dummy().ValueOr(false) &&
+        !emboss_reserved_local_other.has_dummy().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_dummy().ValueOr(false) &&
+        has_dummy().ValueOr(false) &&
+        !dummy().UncheckedEquals(emboss_reserved_local_other.dummy()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericPlaceholder4View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericPlaceholder4View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericPlaceholder4View<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "dummy") {
+        if (!dummy().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_dummy().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          dummy().IsAggregate() || dummy().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("dummy: ");
+        dummy().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !dummy().IsAggregate() && !dummy().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# dummy: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ dummy() const;
+  ::emboss::support::Maybe<bool> has_dummy() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericPlaceholder4View;
+};
+using Placeholder4View =
+    GenericPlaceholder4View</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using Placeholder4Writer =
+    GenericPlaceholder4View</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericPlaceholder4View {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericPlaceholder4View<
+    GenericPlaceholder4View<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericPlaceholder4View<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakePlaceholder4View( T &&emboss_reserved_local_arg) {
+  return GenericPlaceholder4View<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericPlaceholder4View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakePlaceholder4View( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericPlaceholder4View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericPlaceholder4View<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedPlaceholder4View(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericPlaceholder4View<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace Placeholder6 {
+
+}  // namespace Placeholder6
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericPlaceholder6View;
+
+template <class Storage>
+class GenericPlaceholder6View final {
+ public:
+  GenericPlaceholder6View() : backing_() {}
+  explicit GenericPlaceholder6View(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericPlaceholder6View(
+      const GenericPlaceholder6View<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericPlaceholder6View<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericPlaceholder6View(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericPlaceholder6View(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericPlaceholder6View<Storage> &operator=(
+      const GenericPlaceholder6View<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_zero_offset().Known()) return false;
+    if (has_zero_offset().ValueOrDefault() && !zero_offset().Ok()) return false;
+
+
+    if (!has_two_offset().Known()) return false;
+    if (has_two_offset().ValueOrDefault() && !two_offset().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericPlaceholder6View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_zero_offset().Known()) return false;
+    if (!emboss_reserved_local_other.has_zero_offset().Known()) return false;
+
+    if (emboss_reserved_local_other.has_zero_offset().ValueOrDefault() &&
+        !has_zero_offset().ValueOrDefault())
+      return false;
+    if (has_zero_offset().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_zero_offset().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_zero_offset().ValueOrDefault() &&
+        has_zero_offset().ValueOrDefault() &&
+        !zero_offset().Equals(emboss_reserved_local_other.zero_offset()))
+      return false;
+
+
+
+    if (!has_two_offset().Known()) return false;
+    if (!emboss_reserved_local_other.has_two_offset().Known()) return false;
+
+    if (emboss_reserved_local_other.has_two_offset().ValueOrDefault() &&
+        !has_two_offset().ValueOrDefault())
+      return false;
+    if (has_two_offset().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_two_offset().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_two_offset().ValueOrDefault() &&
+        has_two_offset().ValueOrDefault() &&
+        !two_offset().Equals(emboss_reserved_local_other.two_offset()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericPlaceholder6View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_zero_offset().ValueOr(false) &&
+        !has_zero_offset().ValueOr(false))
+      return false;
+    if (has_zero_offset().ValueOr(false) &&
+        !emboss_reserved_local_other.has_zero_offset().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_zero_offset().ValueOr(false) &&
+        has_zero_offset().ValueOr(false) &&
+        !zero_offset().UncheckedEquals(emboss_reserved_local_other.zero_offset()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_two_offset().ValueOr(false) &&
+        !has_two_offset().ValueOr(false))
+      return false;
+    if (has_two_offset().ValueOr(false) &&
+        !emboss_reserved_local_other.has_two_offset().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_two_offset().ValueOr(false) &&
+        has_two_offset().ValueOr(false) &&
+        !two_offset().UncheckedEquals(emboss_reserved_local_other.two_offset()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericPlaceholder6View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericPlaceholder6View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericPlaceholder6View<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "zero_offset") {
+        if (!zero_offset().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "two_offset") {
+        if (!two_offset().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_zero_offset().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          zero_offset().IsAggregate() || zero_offset().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("zero_offset: ");
+        zero_offset().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !zero_offset().IsAggregate() && !zero_offset().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# zero_offset: UNREADABLE\n");
+      }
+    }
+
+    if (has_two_offset().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          two_offset().IsAggregate() || two_offset().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("two_offset: ");
+        two_offset().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !two_offset().IsAggregate() && !two_offset().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# two_offset: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ zero_offset() const;
+  ::emboss::support::Maybe<bool> has_zero_offset() const;
+
+ public:
+  typename ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 2>>
+
+ two_offset() const;
+  ::emboss::support::Maybe<bool> has_two_offset() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericPlaceholder6View;
+};
+using Placeholder6View =
+    GenericPlaceholder6View</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using Placeholder6Writer =
+    GenericPlaceholder6View</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericPlaceholder6View {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericPlaceholder6View<
+    GenericPlaceholder6View<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericPlaceholder6View<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakePlaceholder6View( T &&emboss_reserved_local_arg) {
+  return GenericPlaceholder6View<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericPlaceholder6View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakePlaceholder6View( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericPlaceholder6View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericPlaceholder6View<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedPlaceholder6View(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericPlaceholder6View<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace Alignments {
+
+}  // namespace Alignments
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericAlignmentsView<Storage>::zero_offset()
+    const {
+
+  if ( has_zero_offset().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAlignmentsView<Storage>::has_zero_offset() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericPlaceholder6View<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericAlignmentsView<Storage>::zero_offset_substructure()
+    const {
+
+  if ( has_zero_offset_substructure().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericPlaceholder6View<typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericPlaceholder6View<typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAlignmentsView<Storage>::has_zero_offset_substructure() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericPlaceholder6View<typename Storage::template OffsetStorageType</**/0, 2>>
+
+ GenericAlignmentsView<Storage>::two_offset_substructure()
+    const {
+
+  if ( has_two_offset_substructure().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericPlaceholder6View<typename Storage::template OffsetStorageType</**/0, 2>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericPlaceholder6View<typename Storage::template OffsetStorageType</**/0, 2>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAlignmentsView<Storage>::has_two_offset_substructure() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 3>>
+
+ GenericAlignmentsView<Storage>::three_offset()
+    const {
+
+  if ( has_three_offset().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 3>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   3>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 3>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAlignmentsView<Storage>::has_three_offset() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 4>>
+
+ GenericAlignmentsView<Storage>::four_offset()
+    const {
+
+  if ( has_four_offset().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 4>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   4>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 4>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAlignmentsView<Storage>::has_four_offset() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 11>>
+
+ GenericAlignmentsView<Storage>::eleven_offset()
+    const {
+
+  if ( has_eleven_offset().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(11LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 11>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   11>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 11>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAlignmentsView<Storage>::has_eleven_offset() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 12>>
+
+ GenericAlignmentsView<Storage>::twelve_offset()
+    const {
+
+  if ( has_twelve_offset().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(12LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 12>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   12>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 12>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAlignmentsView<Storage>::has_twelve_offset() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/4, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 4,
+    8 >
+
+ GenericAlignmentsView<Storage>::zero_offset_four_stride_array()
+    const {
+
+  if ( has_zero_offset_four_stride_array().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(12LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/4, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 4,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/4, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 4,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAlignmentsView<Storage>::has_zero_offset_four_stride_array() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericPlaceholder6View<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/6, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 6,
+    8 >
+
+ GenericAlignmentsView<Storage>::zero_offset_six_stride_array()
+    const {
+
+  if ( has_zero_offset_six_stride_array().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(24LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericPlaceholder6View<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/6, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 6,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericPlaceholder6View<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/6, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 6,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAlignmentsView<Storage>::has_zero_offset_six_stride_array() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/4, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 4,
+    8 >
+
+ GenericAlignmentsView<Storage>::three_offset_four_stride_array()
+    const {
+
+  if ( has_three_offset_four_stride_array().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(12LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/4, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 4,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   3>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/4, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 4,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAlignmentsView<Storage>::has_three_offset_four_stride_array() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericPlaceholder6View<typename Storage::template OffsetStorageType</**/0, 4>::template OffsetStorageType</**/6, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 4>, 6,
+    8 >
+
+ GenericAlignmentsView<Storage>::four_offset_six_stride_array()
+    const {
+
+  if ( has_four_offset_six_stride_array().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(24LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericPlaceholder6View<typename Storage::template OffsetStorageType</**/0, 4>::template OffsetStorageType</**/6, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 4>, 6,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   4>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericPlaceholder6View<typename Storage::template OffsetStorageType</**/0, 4>::template OffsetStorageType</**/6, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 4>, 6,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAlignmentsView<Storage>::has_four_offset_six_stride_array() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Alignments {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(28LL)).ValueOrDefault();
+}
+}  // namespace Alignments
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAlignmentsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Alignments::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAlignmentsView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Alignments::IntrinsicSizeInBytes();
+}
+
+namespace Alignments {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(28LL)).ValueOrDefault();
+}
+}  // namespace Alignments
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAlignmentsView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Alignments::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAlignmentsView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Alignments::MaxSizeInBytes();
+}
+
+namespace Alignments {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(28LL)).ValueOrDefault();
+}
+}  // namespace Alignments
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAlignmentsView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Alignments::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAlignmentsView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Alignments::MinSizeInBytes();
+}
+namespace Placeholder4 {
+
+}  // namespace Placeholder4
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ GenericPlaceholder4View<Storage>::dummy()
+    const {
+
+  if ( has_dummy().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericPlaceholder4View<Storage>::has_dummy() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Placeholder4 {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace Placeholder4
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericPlaceholder4View<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Placeholder4::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericPlaceholder4View<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Placeholder4::IntrinsicSizeInBytes();
+}
+
+namespace Placeholder4 {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace Placeholder4
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericPlaceholder4View<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Placeholder4::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericPlaceholder4View<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Placeholder4::MaxSizeInBytes();
+}
+
+namespace Placeholder4 {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace Placeholder4
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericPlaceholder4View<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Placeholder4::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericPlaceholder4View<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Placeholder4::MinSizeInBytes();
+}
+namespace Placeholder6 {
+
+}  // namespace Placeholder6
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericPlaceholder6View<Storage>::zero_offset()
+    const {
+
+  if ( has_zero_offset().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericPlaceholder6View<Storage>::has_zero_offset() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 2>>
+
+ GenericPlaceholder6View<Storage>::two_offset()
+    const {
+
+  if ( has_two_offset().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 2>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericPlaceholder4View<typename Storage::template OffsetStorageType</**/0, 2>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericPlaceholder6View<Storage>::has_two_offset() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Placeholder6 {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL)).ValueOrDefault();
+}
+}  // namespace Placeholder6
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericPlaceholder6View<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Placeholder6::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericPlaceholder6View<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Placeholder6::IntrinsicSizeInBytes();
+}
+
+namespace Placeholder6 {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL)).ValueOrDefault();
+}
+}  // namespace Placeholder6
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericPlaceholder6View<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Placeholder6::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericPlaceholder6View<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Placeholder6::MaxSizeInBytes();
+}
+
+namespace Placeholder6 {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL)).ValueOrDefault();
+}
+}  // namespace Placeholder6
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericPlaceholder6View<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Placeholder6::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericPlaceholder6View<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Placeholder6::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_ALIGNMENTS_EMB_H_
+
diff --git a/testdata/golden_cpp/anonymous_bits.emb.h b/testdata/golden_cpp/anonymous_bits.emb.h
new file mode 100644
index 0000000..7d505c9
--- /dev/null
+++ b/testdata/golden_cpp/anonymous_bits.emb.h
@@ -0,0 +1,2417 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_ANONYMOUS_BITS_EMB_H_
+#define TESTDATA_ANONYMOUS_BITS_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace Foo {
+namespace EmbossReservedAnonymousField2 {
+
+}  // namespace EmbossReservedAnonymousField2
+
+
+template <class Storage>
+class GenericEmbossReservedAnonymousField2View;
+
+
+enum class Bar : ::std::uint64_t;
+
+
+namespace EmbossReservedAnonymousField1 {
+
+}  // namespace EmbossReservedAnonymousField1
+
+
+template <class Storage>
+class GenericEmbossReservedAnonymousField1View;
+
+
+}  // namespace Foo
+
+
+template <class Storage>
+class GenericFooView;
+
+
+
+
+
+
+
+
+
+
+
+namespace Foo {
+
+
+
+
+
+namespace EmbossReservedAnonymousField2 {
+
+}  // namespace EmbossReservedAnonymousField2
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField2View;
+
+template <class Storage>
+class GenericEmbossReservedAnonymousField2View final {
+ public:
+  GenericEmbossReservedAnonymousField2View() : backing_() {}
+  explicit GenericEmbossReservedAnonymousField2View(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEmbossReservedAnonymousField2View(
+      const GenericEmbossReservedAnonymousField2View<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericEmbossReservedAnonymousField2View<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericEmbossReservedAnonymousField2View(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericEmbossReservedAnonymousField2View(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEmbossReservedAnonymousField2View<Storage> &operator=(
+      const GenericEmbossReservedAnonymousField2View<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_high_bit().Known()) return false;
+    if (has_high_bit().ValueOrDefault() && !high_bit().Ok()) return false;
+
+
+    if (!has_bar().Known()) return false;
+    if (has_bar().ValueOrDefault() && !bar().Ok()) return false;
+
+
+    if (!has_first_bit().Known()) return false;
+    if (has_first_bit().ValueOrDefault() && !first_bit().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBits().Known()) return false;
+    if (has_IntrinsicSizeInBits().ValueOrDefault() && !IntrinsicSizeInBits().Ok()) return false;
+
+
+    if (!has_MaxSizeInBits().Known()) return false;
+    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok()) return false;
+
+
+    if (!has_MinSizeInBits().Known()) return false;
+    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBits().Ok() &&
+           backing_.SizeInBits() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBits().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBits() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBits().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBits().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericEmbossReservedAnonymousField2View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_high_bit().Known()) return false;
+    if (!emboss_reserved_local_other.has_high_bit().Known()) return false;
+
+    if (emboss_reserved_local_other.has_high_bit().ValueOrDefault() &&
+        !has_high_bit().ValueOrDefault())
+      return false;
+    if (has_high_bit().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_high_bit().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_high_bit().ValueOrDefault() &&
+        has_high_bit().ValueOrDefault() &&
+        !high_bit().Equals(emboss_reserved_local_other.high_bit()))
+      return false;
+
+
+
+    if (!has_bar().Known()) return false;
+    if (!emboss_reserved_local_other.has_bar().Known()) return false;
+
+    if (emboss_reserved_local_other.has_bar().ValueOrDefault() &&
+        !has_bar().ValueOrDefault())
+      return false;
+    if (has_bar().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_bar().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_bar().ValueOrDefault() &&
+        has_bar().ValueOrDefault() &&
+        !bar().Equals(emboss_reserved_local_other.bar()))
+      return false;
+
+
+
+    if (!has_first_bit().Known()) return false;
+    if (!emboss_reserved_local_other.has_first_bit().Known()) return false;
+
+    if (emboss_reserved_local_other.has_first_bit().ValueOrDefault() &&
+        !has_first_bit().ValueOrDefault())
+      return false;
+    if (has_first_bit().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_first_bit().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_first_bit().ValueOrDefault() &&
+        has_first_bit().ValueOrDefault() &&
+        !first_bit().Equals(emboss_reserved_local_other.first_bit()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericEmbossReservedAnonymousField2View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_high_bit().ValueOr(false) &&
+        !has_high_bit().ValueOr(false))
+      return false;
+    if (has_high_bit().ValueOr(false) &&
+        !emboss_reserved_local_other.has_high_bit().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_high_bit().ValueOr(false) &&
+        has_high_bit().ValueOr(false) &&
+        !high_bit().UncheckedEquals(emboss_reserved_local_other.high_bit()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_bar().ValueOr(false) &&
+        !has_bar().ValueOr(false))
+      return false;
+    if (has_bar().ValueOr(false) &&
+        !emboss_reserved_local_other.has_bar().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_bar().ValueOr(false) &&
+        has_bar().ValueOr(false) &&
+        !bar().UncheckedEquals(emboss_reserved_local_other.bar()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_first_bit().ValueOr(false) &&
+        !has_first_bit().ValueOr(false))
+      return false;
+    if (has_first_bit().ValueOr(false) &&
+        !emboss_reserved_local_other.has_first_bit().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_first_bit().ValueOr(false) &&
+        has_first_bit().ValueOr(false) &&
+        !first_bit().UncheckedEquals(emboss_reserved_local_other.first_bit()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericEmbossReservedAnonymousField2View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericEmbossReservedAnonymousField2View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericEmbossReservedAnonymousField2View<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "high_bit") {
+        if (!high_bit().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "bar") {
+        if (!bar().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "first_bit") {
+        if (!first_bit().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_high_bit().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          high_bit().IsAggregate() || high_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("high_bit: ");
+        high_bit().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !high_bit().IsAggregate() && !high_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# high_bit: UNREADABLE\n");
+      }
+    }
+
+    if (has_bar().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          bar().IsAggregate() || bar().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("bar: ");
+        bar().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !bar().IsAggregate() && !bar().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# bar: UNREADABLE\n");
+      }
+    }
+
+    if (has_first_bit().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          first_bit().IsAggregate() || first_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("first_bit: ");
+        first_bit().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !first_bit().IsAggregate() && !first_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# first_bit: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 31>>
+
+ high_bit() const;
+  ::emboss::support::Maybe<bool> has_high_bit() const;
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Foo::Bar,
+    ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 14>>
+
+ bar() const;
+  ::emboss::support::Maybe<bool> has_bar() const;
+
+ public:
+  typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ first_bit() const;
+  ::emboss::support::Maybe<bool> has_first_bit() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView IntrinsicSizeInBits() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBitsView() {}
+    EmbossReservedDollarVirtualMaxSizeInBitsView(const EmbossReservedDollarVirtualMaxSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView(EmbossReservedDollarVirtualMaxSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(const EmbossReservedDollarVirtualMaxSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(EmbossReservedDollarVirtualMaxSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBitsView MaxSizeInBits() {
+    return EmbossReservedDollarVirtualMaxSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBitsView() {}
+    EmbossReservedDollarVirtualMinSizeInBitsView(const EmbossReservedDollarVirtualMinSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView(EmbossReservedDollarVirtualMinSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(const EmbossReservedDollarVirtualMinSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(EmbossReservedDollarVirtualMinSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBitsView MinSizeInBits() {
+    return EmbossReservedDollarVirtualMinSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericEmbossReservedAnonymousField2View;
+};
+using EmbossReservedAnonymousField2View =
+    GenericEmbossReservedAnonymousField2View</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using EmbossReservedAnonymousField2Writer =
+    GenericEmbossReservedAnonymousField2View</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField2View {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField2View<
+    GenericEmbossReservedAnonymousField2View<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericEmbossReservedAnonymousField2View<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeEmbossReservedAnonymousField2View( T &&emboss_reserved_local_arg) {
+  return GenericEmbossReservedAnonymousField2View<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericEmbossReservedAnonymousField2View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeEmbossReservedAnonymousField2View( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericEmbossReservedAnonymousField2View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericEmbossReservedAnonymousField2View<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedEmbossReservedAnonymousField2View(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericEmbossReservedAnonymousField2View<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+enum class Bar : ::std::uint64_t {
+  BAR = static_cast</**/::std::int32_t>(0LL),
+  BAZ = static_cast</**/::std::int32_t>(1LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<Bar> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   Bar *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("BAR", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Bar::BAR;
+      return true;
+    }
+
+    if (!strcmp("BAZ", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Bar::BAZ;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      Bar emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Bar::BAR: return "BAR";
+
+      case Bar::BAZ: return "BAZ";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(Bar emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Bar::BAR: return true;
+
+      case Bar::BAZ: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       Bar emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<Bar>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    Bar *emboss_reserved_local_result) {
+  return EnumTraits<Bar>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    Bar emboss_reserved_local_value) {
+  return EnumTraits<Bar>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(Bar emboss_reserved_local_value) {
+  return EnumTraits<Bar>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    Bar emboss_reserved_local_value) {
+  return EnumTraits<Bar>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+
+
+
+
+
+namespace EmbossReservedAnonymousField1 {
+
+}  // namespace EmbossReservedAnonymousField1
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View;
+
+template <class Storage>
+class GenericEmbossReservedAnonymousField1View final {
+ public:
+  GenericEmbossReservedAnonymousField1View() : backing_() {}
+  explicit GenericEmbossReservedAnonymousField1View(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEmbossReservedAnonymousField1View(
+      const GenericEmbossReservedAnonymousField1View<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericEmbossReservedAnonymousField1View(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericEmbossReservedAnonymousField1View(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEmbossReservedAnonymousField1View<Storage> &operator=(
+      const GenericEmbossReservedAnonymousField1View<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_bit_23().Known()) return false;
+    if (has_bit_23().ValueOrDefault() && !bit_23().Ok()) return false;
+
+
+    if (!has_low_bit().Known()) return false;
+    if (has_low_bit().ValueOrDefault() && !low_bit().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBits().Known()) return false;
+    if (has_IntrinsicSizeInBits().ValueOrDefault() && !IntrinsicSizeInBits().Ok()) return false;
+
+
+    if (!has_MaxSizeInBits().Known()) return false;
+    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok()) return false;
+
+
+    if (!has_MinSizeInBits().Known()) return false;
+    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBits().Ok() &&
+           backing_.SizeInBits() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBits().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBits() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBits().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBits().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_bit_23().Known()) return false;
+    if (!emboss_reserved_local_other.has_bit_23().Known()) return false;
+
+    if (emboss_reserved_local_other.has_bit_23().ValueOrDefault() &&
+        !has_bit_23().ValueOrDefault())
+      return false;
+    if (has_bit_23().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_bit_23().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_bit_23().ValueOrDefault() &&
+        has_bit_23().ValueOrDefault() &&
+        !bit_23().Equals(emboss_reserved_local_other.bit_23()))
+      return false;
+
+
+
+    if (!has_low_bit().Known()) return false;
+    if (!emboss_reserved_local_other.has_low_bit().Known()) return false;
+
+    if (emboss_reserved_local_other.has_low_bit().ValueOrDefault() &&
+        !has_low_bit().ValueOrDefault())
+      return false;
+    if (has_low_bit().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_low_bit().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_low_bit().ValueOrDefault() &&
+        has_low_bit().ValueOrDefault() &&
+        !low_bit().Equals(emboss_reserved_local_other.low_bit()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_bit_23().ValueOr(false) &&
+        !has_bit_23().ValueOr(false))
+      return false;
+    if (has_bit_23().ValueOr(false) &&
+        !emboss_reserved_local_other.has_bit_23().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_bit_23().ValueOr(false) &&
+        has_bit_23().ValueOr(false) &&
+        !bit_23().UncheckedEquals(emboss_reserved_local_other.bit_23()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_low_bit().ValueOr(false) &&
+        !has_low_bit().ValueOr(false))
+      return false;
+    if (has_low_bit().ValueOr(false) &&
+        !emboss_reserved_local_other.has_low_bit().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_low_bit().ValueOr(false) &&
+        has_low_bit().ValueOr(false) &&
+        !low_bit().UncheckedEquals(emboss_reserved_local_other.low_bit()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "bit_23") {
+        if (!bit_23().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "low_bit") {
+        if (!low_bit().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_bit_23().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          bit_23().IsAggregate() || bit_23().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("bit_23: ");
+        bit_23().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !bit_23().IsAggregate() && !bit_23().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# bit_23: UNREADABLE\n");
+      }
+    }
+
+    if (has_low_bit().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          low_bit().IsAggregate() || low_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("low_bit: ");
+        low_bit().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !low_bit().IsAggregate() && !low_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# low_bit: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 23>>
+
+ bit_23() const;
+  ::emboss::support::Maybe<bool> has_bit_23() const;
+
+ public:
+  typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ low_bit() const;
+  ::emboss::support::Maybe<bool> has_low_bit() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView IntrinsicSizeInBits() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBitsView() {}
+    EmbossReservedDollarVirtualMaxSizeInBitsView(const EmbossReservedDollarVirtualMaxSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView(EmbossReservedDollarVirtualMaxSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(const EmbossReservedDollarVirtualMaxSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(EmbossReservedDollarVirtualMaxSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBitsView MaxSizeInBits() {
+    return EmbossReservedDollarVirtualMaxSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBitsView() {}
+    EmbossReservedDollarVirtualMinSizeInBitsView(const EmbossReservedDollarVirtualMinSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView(EmbossReservedDollarVirtualMinSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(const EmbossReservedDollarVirtualMinSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(EmbossReservedDollarVirtualMinSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBitsView MinSizeInBits() {
+    return EmbossReservedDollarVirtualMinSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericEmbossReservedAnonymousField1View;
+};
+using EmbossReservedAnonymousField1View =
+    GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using EmbossReservedAnonymousField1Writer =
+    GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View<
+    GenericEmbossReservedAnonymousField1View<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericEmbossReservedAnonymousField1View<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeEmbossReservedAnonymousField1View( T &&emboss_reserved_local_arg) {
+  return GenericEmbossReservedAnonymousField1View<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeEmbossReservedAnonymousField1View( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericEmbossReservedAnonymousField1View<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedEmbossReservedAnonymousField1View(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericEmbossReservedAnonymousField1View<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+}  // namespace Foo
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericFooView;
+
+template <class Storage>
+class GenericFooView final {
+ public:
+  GenericFooView() : backing_() {}
+  explicit GenericFooView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericFooView(
+      const GenericFooView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericFooView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericFooView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericFooView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericFooView<Storage> &operator=(
+      const GenericFooView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+    using Bar = ::emboss::test::Foo::Bar;
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_emboss_reserved_anonymous_field_2().Known()) return false;
+    if (has_emboss_reserved_anonymous_field_2().ValueOrDefault() && !emboss_reserved_anonymous_field_2().Ok()) return false;
+
+
+    if (!has_high_bit().Known()) return false;
+    if (has_high_bit().ValueOrDefault() && !high_bit().Ok()) return false;
+
+
+    if (!has_bar().Known()) return false;
+    if (has_bar().ValueOrDefault() && !bar().Ok()) return false;
+
+
+    if (!has_first_bit().Known()) return false;
+    if (has_first_bit().ValueOrDefault() && !first_bit().Ok()) return false;
+
+
+    if (!has_emboss_reserved_anonymous_field_1().Known()) return false;
+    if (has_emboss_reserved_anonymous_field_1().ValueOrDefault() && !emboss_reserved_anonymous_field_1().Ok()) return false;
+
+
+    if (!has_bit_23().Known()) return false;
+    if (has_bit_23().ValueOrDefault() && !bit_23().Ok()) return false;
+
+
+    if (!has_low_bit().Known()) return false;
+    if (has_low_bit().ValueOrDefault() && !low_bit().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericFooView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_emboss_reserved_anonymous_field_2().Known()) return false;
+    if (!emboss_reserved_local_other.has_emboss_reserved_anonymous_field_2().Known()) return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_2().ValueOrDefault() &&
+        !has_emboss_reserved_anonymous_field_2().ValueOrDefault())
+      return false;
+    if (has_emboss_reserved_anonymous_field_2().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_emboss_reserved_anonymous_field_2().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_2().ValueOrDefault() &&
+        has_emboss_reserved_anonymous_field_2().ValueOrDefault() &&
+        !emboss_reserved_anonymous_field_2().Equals(emboss_reserved_local_other.emboss_reserved_anonymous_field_2()))
+      return false;
+
+
+
+    if (!has_emboss_reserved_anonymous_field_1().Known()) return false;
+    if (!emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().Known()) return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        !has_emboss_reserved_anonymous_field_1().ValueOrDefault())
+      return false;
+    if (has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        !emboss_reserved_anonymous_field_1().Equals(emboss_reserved_local_other.emboss_reserved_anonymous_field_1()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericFooView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_2().ValueOr(false) &&
+        !has_emboss_reserved_anonymous_field_2().ValueOr(false))
+      return false;
+    if (has_emboss_reserved_anonymous_field_2().ValueOr(false) &&
+        !emboss_reserved_local_other.has_emboss_reserved_anonymous_field_2().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_2().ValueOr(false) &&
+        has_emboss_reserved_anonymous_field_2().ValueOr(false) &&
+        !emboss_reserved_anonymous_field_2().UncheckedEquals(emboss_reserved_local_other.emboss_reserved_anonymous_field_2()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        !has_emboss_reserved_anonymous_field_1().ValueOr(false))
+      return false;
+    if (has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        !emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        !emboss_reserved_anonymous_field_1().UncheckedEquals(emboss_reserved_local_other.emboss_reserved_anonymous_field_1()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericFooView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericFooView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericFooView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "high_bit") {
+        if (!high_bit().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "bar") {
+        if (!bar().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "first_bit") {
+        if (!first_bit().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "bit_23") {
+        if (!bit_23().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "low_bit") {
+        if (!low_bit().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_high_bit().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          high_bit().IsAggregate() || high_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("high_bit: ");
+        high_bit().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !high_bit().IsAggregate() && !high_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# high_bit: UNREADABLE\n");
+      }
+    }
+
+    if (has_bar().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          bar().IsAggregate() || bar().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("bar: ");
+        bar().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !bar().IsAggregate() && !bar().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# bar: UNREADABLE\n");
+      }
+    }
+
+    if (has_first_bit().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          first_bit().IsAggregate() || first_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("first_bit: ");
+        first_bit().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !first_bit().IsAggregate() && !first_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# first_bit: UNREADABLE\n");
+      }
+    }
+
+    if (has_bit_23().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          bit_23().IsAggregate() || bit_23().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("bit_23: ");
+        bit_23().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !bit_23().IsAggregate() && !bit_23().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# bit_23: UNREADABLE\n");
+      }
+    }
+
+    if (has_low_bit().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          low_bit().IsAggregate() || low_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("low_bit: ");
+        low_bit().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !low_bit().IsAggregate() && !low_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# low_bit: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ private:
+  typename ::emboss::test::Foo::GenericEmbossReservedAnonymousField2View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ emboss_reserved_anonymous_field_2() const;
+  ::emboss::support::Maybe<bool> has_emboss_reserved_anonymous_field_2() const;
+
+ public:
+  auto high_bit() const -> decltype(this->emboss_reserved_anonymous_field_2().high_bit()) {
+   return has_high_bit().ValueOrDefault() ? emboss_reserved_anonymous_field_2().high_bit()
+                                          : decltype(this->emboss_reserved_anonymous_field_2().high_bit())();
+  }
+  ::emboss::support::Maybe<bool> has_high_bit() const;
+
+ public:
+  auto bar() const -> decltype(this->emboss_reserved_anonymous_field_2().bar()) {
+   return has_bar().ValueOrDefault() ? emboss_reserved_anonymous_field_2().bar()
+                                          : decltype(this->emboss_reserved_anonymous_field_2().bar())();
+  }
+  ::emboss::support::Maybe<bool> has_bar() const;
+
+ public:
+  auto first_bit() const -> decltype(this->emboss_reserved_anonymous_field_2().first_bit()) {
+   return has_first_bit().ValueOrDefault() ? emboss_reserved_anonymous_field_2().first_bit()
+                                          : decltype(this->emboss_reserved_anonymous_field_2().first_bit())();
+  }
+  ::emboss::support::Maybe<bool> has_first_bit() const;
+
+ private:
+  typename ::emboss::test::Foo::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+ emboss_reserved_anonymous_field_1() const;
+  ::emboss::support::Maybe<bool> has_emboss_reserved_anonymous_field_1() const;
+
+ public:
+  auto bit_23() const -> decltype(this->emboss_reserved_anonymous_field_1().bit_23()) {
+   return has_bit_23().ValueOrDefault() ? emboss_reserved_anonymous_field_1().bit_23()
+                                          : decltype(this->emboss_reserved_anonymous_field_1().bit_23())();
+  }
+  ::emboss::support::Maybe<bool> has_bit_23() const;
+
+ public:
+  auto low_bit() const -> decltype(this->emboss_reserved_anonymous_field_1().low_bit()) {
+   return has_low_bit().ValueOrDefault() ? emboss_reserved_anonymous_field_1().low_bit()
+                                          : decltype(this->emboss_reserved_anonymous_field_1().low_bit())();
+  }
+  ::emboss::support::Maybe<bool> has_low_bit() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericFooView;
+};
+using FooView =
+    GenericFooView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using FooWriter =
+    GenericFooView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericFooView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericFooView<
+    GenericFooView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericFooView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeFooView( T &&emboss_reserved_local_arg) {
+  return GenericFooView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericFooView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeFooView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericFooView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericFooView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedFooView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericFooView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace Foo {
+namespace EmbossReservedAnonymousField2 {
+
+}  // namespace EmbossReservedAnonymousField2
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 31>>
+
+ GenericEmbossReservedAnonymousField2View<Storage>::high_bit()
+    const {
+
+  if ( has_high_bit().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(31LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 31>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   31>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 31>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField2View<Storage>::has_high_bit() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Foo::Bar,
+    ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 14>>
+
+ GenericEmbossReservedAnonymousField2View<Storage>::bar()
+    const {
+
+  if ( has_bar().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(14LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Foo::Bar,
+    ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 14>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   14>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Foo::Bar,
+    ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 14>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField2View<Storage>::has_bar() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericEmbossReservedAnonymousField2View<Storage>::first_bit()
+    const {
+
+  if ( has_first_bit().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField2View<Storage>::has_first_bit() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace EmbossReservedAnonymousField2 {
+inline constexpr ::std::int32_t IntrinsicSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(32LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField2
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField2View<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField2::IntrinsicSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField2View<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField2::IntrinsicSizeInBits();
+}
+
+namespace EmbossReservedAnonymousField2 {
+inline constexpr ::std::int32_t MaxSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(32LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField2
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField2View<Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField2::MaxSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField2View<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField2::MaxSizeInBits();
+}
+
+namespace EmbossReservedAnonymousField2 {
+inline constexpr ::std::int32_t MinSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(32LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField2
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField2View<Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField2::MinSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField2View<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField2::MinSizeInBits();
+}
+
+
+namespace EmbossReservedAnonymousField1 {
+
+}  // namespace EmbossReservedAnonymousField1
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 23>>
+
+ GenericEmbossReservedAnonymousField1View<Storage>::bit_23()
+    const {
+
+  if ( has_bit_23().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(23LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 23>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   23>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 23>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField1View<Storage>::has_bit_23() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericEmbossReservedAnonymousField1View<Storage>::low_bit()
+    const {
+
+  if ( has_low_bit().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField1View<Storage>::has_low_bit() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace EmbossReservedAnonymousField1 {
+inline constexpr ::std::int32_t IntrinsicSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(24LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField1
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField1::IntrinsicSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField1::IntrinsicSizeInBits();
+}
+
+namespace EmbossReservedAnonymousField1 {
+inline constexpr ::std::int32_t MaxSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(24LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField1
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField1::MaxSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField1::MaxSizeInBits();
+}
+
+namespace EmbossReservedAnonymousField1 {
+inline constexpr ::std::int32_t MinSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(24LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField1
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField1::MinSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField1::MinSizeInBits();
+}
+
+}  // namespace Foo
+
+
+template <class Storage>
+inline typename ::emboss::test::Foo::GenericEmbossReservedAnonymousField2View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ GenericFooView<Storage>::emboss_reserved_anonymous_field_2()
+    const {
+
+  if ( has_emboss_reserved_anonymous_field_2().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::Foo::GenericEmbossReservedAnonymousField2View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::Foo::GenericEmbossReservedAnonymousField2View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericFooView<Storage>::has_emboss_reserved_anonymous_field_2() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericFooView<Storage>::has_high_bit() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericFooView<Storage>::has_bar() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericFooView<Storage>::has_first_bit() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::Foo::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+ GenericFooView<Storage>::emboss_reserved_anonymous_field_1()
+    const {
+
+  if ( has_emboss_reserved_anonymous_field_1().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::Foo::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   4>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::Foo::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericFooView<Storage>::has_emboss_reserved_anonymous_field_1() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericFooView<Storage>::has_bit_23() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericFooView<Storage>::has_low_bit() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+namespace Foo {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace Foo
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFooView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Foo::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFooView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Foo::IntrinsicSizeInBytes();
+}
+
+namespace Foo {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace Foo
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFooView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Foo::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFooView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Foo::MaxSizeInBytes();
+}
+
+namespace Foo {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace Foo
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFooView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Foo::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFooView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Foo::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_ANONYMOUS_BITS_EMB_H_
+
diff --git a/testdata/golden_cpp/auto_array_size.emb.h b/testdata/golden_cpp/auto_array_size.emb.h
new file mode 100644
index 0000000..64e2973
--- /dev/null
+++ b/testdata/golden_cpp/auto_array_size.emb.h
@@ -0,0 +1,1803 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_AUTO_ARRAY_SIZE_EMB_H_
+#define TESTDATA_AUTO_ARRAY_SIZE_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace Element {
+
+}  // namespace Element
+
+
+template <class Storage>
+class GenericElementView;
+
+namespace AutoSize {
+
+}  // namespace AutoSize
+
+
+template <class Storage>
+class GenericAutoSizeView;
+
+
+
+
+
+
+namespace Element {
+
+}  // namespace Element
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericElementView;
+
+template <class Storage>
+class GenericElementView final {
+ public:
+  GenericElementView() : backing_() {}
+  explicit GenericElementView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericElementView(
+      const GenericElementView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericElementView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericElementView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericElementView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericElementView<Storage> &operator=(
+      const GenericElementView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_a().Known()) return false;
+    if (has_a().ValueOrDefault() && !a().Ok()) return false;
+
+
+    if (!has_b().Known()) return false;
+    if (has_b().ValueOrDefault() && !b().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericElementView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_a().Known()) return false;
+    if (!emboss_reserved_local_other.has_a().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        !has_a().ValueOrDefault())
+      return false;
+    if (has_a().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        has_a().ValueOrDefault() &&
+        !a().Equals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (!has_b().Known()) return false;
+    if (!emboss_reserved_local_other.has_b().Known()) return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        !has_b().ValueOrDefault())
+      return false;
+    if (has_b().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_b().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        has_b().ValueOrDefault() &&
+        !b().Equals(emboss_reserved_local_other.b()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericElementView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        !has_a().ValueOr(false))
+      return false;
+    if (has_a().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        has_a().ValueOr(false) &&
+        !a().UncheckedEquals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        !has_b().ValueOr(false))
+      return false;
+    if (has_b().ValueOr(false) &&
+        !emboss_reserved_local_other.has_b().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        has_b().ValueOr(false) &&
+        !b().UncheckedEquals(emboss_reserved_local_other.b()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericElementView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericElementView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericElementView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "a") {
+        if (!a().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "b") {
+        if (!b().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_a().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a().IsAggregate() || a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a: ");
+        a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a().IsAggregate() && !a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a: UNREADABLE\n");
+      }
+    }
+
+    if (has_b().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b().IsAggregate() || b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("b: ");
+        b().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !b().IsAggregate() && !b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ a() const;
+  ::emboss::support::Maybe<bool> has_a() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ b() const;
+  ::emboss::support::Maybe<bool> has_b() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericElementView;
+};
+using ElementView =
+    GenericElementView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ElementWriter =
+    GenericElementView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericElementView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericElementView<
+    GenericElementView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericElementView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeElementView( T &&emboss_reserved_local_arg) {
+  return GenericElementView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericElementView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeElementView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericElementView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericElementView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedElementView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericElementView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+
+
+namespace AutoSize {
+
+}  // namespace AutoSize
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericAutoSizeView;
+
+template <class Storage>
+class GenericAutoSizeView final {
+ public:
+  GenericAutoSizeView() : backing_() {}
+  explicit GenericAutoSizeView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericAutoSizeView(
+      const GenericAutoSizeView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericAutoSizeView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericAutoSizeView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericAutoSizeView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericAutoSizeView<Storage> &operator=(
+      const GenericAutoSizeView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_array_size().Known()) return false;
+    if (has_array_size().ValueOrDefault() && !array_size().Ok()) return false;
+
+
+    if (!has_four_byte_array().Known()) return false;
+    if (has_four_byte_array().ValueOrDefault() && !four_byte_array().Ok()) return false;
+
+
+    if (!has_four_struct_array().Known()) return false;
+    if (has_four_struct_array().ValueOrDefault() && !four_struct_array().Ok()) return false;
+
+
+    if (!has_dynamic_byte_array().Known()) return false;
+    if (has_dynamic_byte_array().ValueOrDefault() && !dynamic_byte_array().Ok()) return false;
+
+
+    if (!has_dynamic_struct_array().Known()) return false;
+    if (has_dynamic_struct_array().ValueOrDefault() && !dynamic_struct_array().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericAutoSizeView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_array_size().Known()) return false;
+    if (!emboss_reserved_local_other.has_array_size().Known()) return false;
+
+    if (emboss_reserved_local_other.has_array_size().ValueOrDefault() &&
+        !has_array_size().ValueOrDefault())
+      return false;
+    if (has_array_size().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_array_size().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_array_size().ValueOrDefault() &&
+        has_array_size().ValueOrDefault() &&
+        !array_size().Equals(emboss_reserved_local_other.array_size()))
+      return false;
+
+
+
+    if (!has_four_byte_array().Known()) return false;
+    if (!emboss_reserved_local_other.has_four_byte_array().Known()) return false;
+
+    if (emboss_reserved_local_other.has_four_byte_array().ValueOrDefault() &&
+        !has_four_byte_array().ValueOrDefault())
+      return false;
+    if (has_four_byte_array().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_four_byte_array().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_four_byte_array().ValueOrDefault() &&
+        has_four_byte_array().ValueOrDefault() &&
+        !four_byte_array().Equals(emboss_reserved_local_other.four_byte_array()))
+      return false;
+
+
+
+    if (!has_four_struct_array().Known()) return false;
+    if (!emboss_reserved_local_other.has_four_struct_array().Known()) return false;
+
+    if (emboss_reserved_local_other.has_four_struct_array().ValueOrDefault() &&
+        !has_four_struct_array().ValueOrDefault())
+      return false;
+    if (has_four_struct_array().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_four_struct_array().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_four_struct_array().ValueOrDefault() &&
+        has_four_struct_array().ValueOrDefault() &&
+        !four_struct_array().Equals(emboss_reserved_local_other.four_struct_array()))
+      return false;
+
+
+
+    if (!has_dynamic_byte_array().Known()) return false;
+    if (!emboss_reserved_local_other.has_dynamic_byte_array().Known()) return false;
+
+    if (emboss_reserved_local_other.has_dynamic_byte_array().ValueOrDefault() &&
+        !has_dynamic_byte_array().ValueOrDefault())
+      return false;
+    if (has_dynamic_byte_array().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_dynamic_byte_array().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_dynamic_byte_array().ValueOrDefault() &&
+        has_dynamic_byte_array().ValueOrDefault() &&
+        !dynamic_byte_array().Equals(emboss_reserved_local_other.dynamic_byte_array()))
+      return false;
+
+
+
+    if (!has_dynamic_struct_array().Known()) return false;
+    if (!emboss_reserved_local_other.has_dynamic_struct_array().Known()) return false;
+
+    if (emboss_reserved_local_other.has_dynamic_struct_array().ValueOrDefault() &&
+        !has_dynamic_struct_array().ValueOrDefault())
+      return false;
+    if (has_dynamic_struct_array().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_dynamic_struct_array().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_dynamic_struct_array().ValueOrDefault() &&
+        has_dynamic_struct_array().ValueOrDefault() &&
+        !dynamic_struct_array().Equals(emboss_reserved_local_other.dynamic_struct_array()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericAutoSizeView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_array_size().ValueOr(false) &&
+        !has_array_size().ValueOr(false))
+      return false;
+    if (has_array_size().ValueOr(false) &&
+        !emboss_reserved_local_other.has_array_size().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_array_size().ValueOr(false) &&
+        has_array_size().ValueOr(false) &&
+        !array_size().UncheckedEquals(emboss_reserved_local_other.array_size()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_four_byte_array().ValueOr(false) &&
+        !has_four_byte_array().ValueOr(false))
+      return false;
+    if (has_four_byte_array().ValueOr(false) &&
+        !emboss_reserved_local_other.has_four_byte_array().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_four_byte_array().ValueOr(false) &&
+        has_four_byte_array().ValueOr(false) &&
+        !four_byte_array().UncheckedEquals(emboss_reserved_local_other.four_byte_array()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_four_struct_array().ValueOr(false) &&
+        !has_four_struct_array().ValueOr(false))
+      return false;
+    if (has_four_struct_array().ValueOr(false) &&
+        !emboss_reserved_local_other.has_four_struct_array().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_four_struct_array().ValueOr(false) &&
+        has_four_struct_array().ValueOr(false) &&
+        !four_struct_array().UncheckedEquals(emboss_reserved_local_other.four_struct_array()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_dynamic_byte_array().ValueOr(false) &&
+        !has_dynamic_byte_array().ValueOr(false))
+      return false;
+    if (has_dynamic_byte_array().ValueOr(false) &&
+        !emboss_reserved_local_other.has_dynamic_byte_array().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_dynamic_byte_array().ValueOr(false) &&
+        has_dynamic_byte_array().ValueOr(false) &&
+        !dynamic_byte_array().UncheckedEquals(emboss_reserved_local_other.dynamic_byte_array()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_dynamic_struct_array().ValueOr(false) &&
+        !has_dynamic_struct_array().ValueOr(false))
+      return false;
+    if (has_dynamic_struct_array().ValueOr(false) &&
+        !emboss_reserved_local_other.has_dynamic_struct_array().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_dynamic_struct_array().ValueOr(false) &&
+        has_dynamic_struct_array().ValueOr(false) &&
+        !dynamic_struct_array().UncheckedEquals(emboss_reserved_local_other.dynamic_struct_array()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericAutoSizeView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericAutoSizeView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericAutoSizeView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "array_size") {
+        if (!array_size().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "four_byte_array") {
+        if (!four_byte_array().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "four_struct_array") {
+        if (!four_struct_array().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "dynamic_byte_array") {
+        if (!dynamic_byte_array().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "dynamic_struct_array") {
+        if (!dynamic_struct_array().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_array_size().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          array_size().IsAggregate() || array_size().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("array_size: ");
+        array_size().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !array_size().IsAggregate() && !array_size().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# array_size: UNREADABLE\n");
+      }
+    }
+
+    if (has_four_byte_array().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          four_byte_array().IsAggregate() || four_byte_array().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("four_byte_array: ");
+        four_byte_array().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !four_byte_array().IsAggregate() && !four_byte_array().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# four_byte_array: UNREADABLE\n");
+      }
+    }
+
+    if (has_four_struct_array().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          four_struct_array().IsAggregate() || four_struct_array().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("four_struct_array: ");
+        four_struct_array().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !four_struct_array().IsAggregate() && !four_struct_array().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# four_struct_array: UNREADABLE\n");
+      }
+    }
+
+    if (has_dynamic_byte_array().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          dynamic_byte_array().IsAggregate() || dynamic_byte_array().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("dynamic_byte_array: ");
+        dynamic_byte_array().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !dynamic_byte_array().IsAggregate() && !dynamic_byte_array().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# dynamic_byte_array: UNREADABLE\n");
+      }
+    }
+
+    if (has_dynamic_struct_array().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          dynamic_struct_array().IsAggregate() || dynamic_struct_array().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("dynamic_struct_array: ");
+        dynamic_struct_array().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !dynamic_struct_array().IsAggregate() && !dynamic_struct_array().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# dynamic_struct_array: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ array_size() const;
+  ::emboss::support::Maybe<bool> has_array_size() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 1>, 1,
+    8 >
+
+ four_byte_array() const;
+  ::emboss::support::Maybe<bool> has_four_byte_array() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericElementView<typename Storage::template OffsetStorageType</**/0, 5>::template OffsetStorageType</**/2, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 5>, 2,
+    8 >
+
+ four_struct_array() const;
+  ::emboss::support::Maybe<bool> has_four_struct_array() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 13>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 13>, 1,
+    8 >
+
+ dynamic_byte_array() const;
+  ::emboss::support::Maybe<bool> has_dynamic_byte_array() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericElementView<typename Storage::template OffsetStorageType</**/1, 0>::template OffsetStorageType</**/2, 0>>
+
+, typename Storage::template OffsetStorageType</**/1, 0>, 2,
+    8 >
+
+ dynamic_struct_array() const;
+  ::emboss::support::Maybe<bool> has_dynamic_struct_array() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericAutoSizeView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.array_size();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(13LL)), emboss_reserved_local_subexpr_2);
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Product</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), emboss_reserved_local_subexpr_2);
+      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, emboss_reserved_local_subexpr_5);
+      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_6, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_8 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(13LL)), emboss_reserved_local_subexpr_4, emboss_reserved_local_subexpr_7);
+
+      return emboss_reserved_local_subexpr_8;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericAutoSizeView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericAutoSizeView;
+};
+using AutoSizeView =
+    GenericAutoSizeView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using AutoSizeWriter =
+    GenericAutoSizeView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericAutoSizeView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericAutoSizeView<
+    GenericAutoSizeView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericAutoSizeView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeAutoSizeView( T &&emboss_reserved_local_arg) {
+  return GenericAutoSizeView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericAutoSizeView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeAutoSizeView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericAutoSizeView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericAutoSizeView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedAutoSizeView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericAutoSizeView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace Element {
+
+}  // namespace Element
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericElementView<Storage>::a()
+    const {
+
+  if ( has_a().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericElementView<Storage>::has_a() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericElementView<Storage>::b()
+    const {
+
+  if ( has_b().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericElementView<Storage>::has_b() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Element {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace Element
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericElementView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Element::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericElementView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Element::IntrinsicSizeInBytes();
+}
+
+namespace Element {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace Element
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericElementView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Element::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericElementView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Element::MaxSizeInBytes();
+}
+
+namespace Element {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace Element
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericElementView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Element::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericElementView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Element::MinSizeInBytes();
+}
+namespace AutoSize {
+
+}  // namespace AutoSize
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericAutoSizeView<Storage>::array_size()
+    const {
+
+  if ( has_array_size().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAutoSizeView<Storage>::has_array_size() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 1>, 1,
+    8 >
+
+ GenericAutoSizeView<Storage>::four_byte_array()
+    const {
+
+  if ( has_four_byte_array().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 1>, 1,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 1>, 1,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAutoSizeView<Storage>::has_four_byte_array() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericElementView<typename Storage::template OffsetStorageType</**/0, 5>::template OffsetStorageType</**/2, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 5>, 2,
+    8 >
+
+ GenericAutoSizeView<Storage>::four_struct_array()
+    const {
+
+  if ( has_four_struct_array().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericElementView<typename Storage::template OffsetStorageType</**/0, 5>::template OffsetStorageType</**/2, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 5>, 2,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   5>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericElementView<typename Storage::template OffsetStorageType</**/0, 5>::template OffsetStorageType</**/2, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 5>, 2,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAutoSizeView<Storage>::has_four_struct_array() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 13>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 13>, 1,
+    8 >
+
+ GenericAutoSizeView<Storage>::dynamic_byte_array()
+    const {
+
+  if ( has_dynamic_byte_array().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = array_size();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_2;
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(13LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 13>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 13>, 1,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   13>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 13>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 13>, 1,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAutoSizeView<Storage>::has_dynamic_byte_array() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericElementView<typename Storage::template OffsetStorageType</**/1, 0>::template OffsetStorageType</**/2, 0>>
+
+, typename Storage::template OffsetStorageType</**/1, 0>, 2,
+    8 >
+
+ GenericAutoSizeView<Storage>::dynamic_struct_array()
+    const {
+
+  if ( has_dynamic_struct_array().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = array_size();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(13LL)), emboss_reserved_local_subexpr_2);
+    const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Product</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), emboss_reserved_local_subexpr_2);
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_4;
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_3;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericElementView<typename Storage::template OffsetStorageType</**/1, 0>::template OffsetStorageType</**/2, 0>>
+
+, typename Storage::template OffsetStorageType</**/1, 0>, 2,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericElementView<typename Storage::template OffsetStorageType</**/1, 0>::template OffsetStorageType</**/2, 0>>
+
+, typename Storage::template OffsetStorageType</**/1, 0>, 2,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAutoSizeView<Storage>::has_dynamic_struct_array() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericAutoSizeView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericAutoSizeView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericAutoSizeView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAutoSizeView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace AutoSize {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(778LL)).ValueOrDefault();
+}
+}  // namespace AutoSize
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAutoSizeView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return AutoSize::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAutoSizeView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return AutoSize::MaxSizeInBytes();
+}
+
+namespace AutoSize {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(13LL)).ValueOrDefault();
+}
+}  // namespace AutoSize
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAutoSizeView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return AutoSize::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAutoSizeView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return AutoSize::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_AUTO_ARRAY_SIZE_EMB_H_
+
diff --git a/testdata/golden_cpp/bcd.emb.h b/testdata/golden_cpp/bcd.emb.h
new file mode 100644
index 0000000..1e4edc2
--- /dev/null
+++ b/testdata/golden_cpp/bcd.emb.h
@@ -0,0 +1,3175 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_BCD_EMB_H_
+#define TESTDATA_BCD_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace BcdSizes {
+namespace EmbossReservedAnonymousField1 {
+
+}  // namespace EmbossReservedAnonymousField1
+
+
+template <class Storage>
+class GenericEmbossReservedAnonymousField1View;
+
+
+}  // namespace BcdSizes
+
+
+template <class Storage>
+class GenericBcdSizesView;
+
+namespace BcdBigEndian {
+
+}  // namespace BcdBigEndian
+
+
+template <class Storage>
+class GenericBcdBigEndianView;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+namespace BcdSizes {
+
+
+
+
+
+
+namespace EmbossReservedAnonymousField1 {
+
+}  // namespace EmbossReservedAnonymousField1
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View;
+
+template <class Storage>
+class GenericEmbossReservedAnonymousField1View final {
+ public:
+  GenericEmbossReservedAnonymousField1View() : backing_() {}
+  explicit GenericEmbossReservedAnonymousField1View(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEmbossReservedAnonymousField1View(
+      const GenericEmbossReservedAnonymousField1View<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericEmbossReservedAnonymousField1View(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericEmbossReservedAnonymousField1View(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEmbossReservedAnonymousField1View<Storage> &operator=(
+      const GenericEmbossReservedAnonymousField1View<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_four_bit().Known()) return false;
+    if (has_four_bit().ValueOrDefault() && !four_bit().Ok()) return false;
+
+
+    if (!has_six_bit().Known()) return false;
+    if (has_six_bit().ValueOrDefault() && !six_bit().Ok()) return false;
+
+
+    if (!has_ten_bit().Known()) return false;
+    if (has_ten_bit().ValueOrDefault() && !ten_bit().Ok()) return false;
+
+
+    if (!has_twelve_bit().Known()) return false;
+    if (has_twelve_bit().ValueOrDefault() && !twelve_bit().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBits().Known()) return false;
+    if (has_IntrinsicSizeInBits().ValueOrDefault() && !IntrinsicSizeInBits().Ok()) return false;
+
+
+    if (!has_MaxSizeInBits().Known()) return false;
+    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok()) return false;
+
+
+    if (!has_MinSizeInBits().Known()) return false;
+    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBits().Ok() &&
+           backing_.SizeInBits() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBits().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBits() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBits().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBits().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_four_bit().Known()) return false;
+    if (!emboss_reserved_local_other.has_four_bit().Known()) return false;
+
+    if (emboss_reserved_local_other.has_four_bit().ValueOrDefault() &&
+        !has_four_bit().ValueOrDefault())
+      return false;
+    if (has_four_bit().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_four_bit().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_four_bit().ValueOrDefault() &&
+        has_four_bit().ValueOrDefault() &&
+        !four_bit().Equals(emboss_reserved_local_other.four_bit()))
+      return false;
+
+
+
+    if (!has_six_bit().Known()) return false;
+    if (!emboss_reserved_local_other.has_six_bit().Known()) return false;
+
+    if (emboss_reserved_local_other.has_six_bit().ValueOrDefault() &&
+        !has_six_bit().ValueOrDefault())
+      return false;
+    if (has_six_bit().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_six_bit().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_six_bit().ValueOrDefault() &&
+        has_six_bit().ValueOrDefault() &&
+        !six_bit().Equals(emboss_reserved_local_other.six_bit()))
+      return false;
+
+
+
+    if (!has_ten_bit().Known()) return false;
+    if (!emboss_reserved_local_other.has_ten_bit().Known()) return false;
+
+    if (emboss_reserved_local_other.has_ten_bit().ValueOrDefault() &&
+        !has_ten_bit().ValueOrDefault())
+      return false;
+    if (has_ten_bit().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_ten_bit().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_ten_bit().ValueOrDefault() &&
+        has_ten_bit().ValueOrDefault() &&
+        !ten_bit().Equals(emboss_reserved_local_other.ten_bit()))
+      return false;
+
+
+
+    if (!has_twelve_bit().Known()) return false;
+    if (!emboss_reserved_local_other.has_twelve_bit().Known()) return false;
+
+    if (emboss_reserved_local_other.has_twelve_bit().ValueOrDefault() &&
+        !has_twelve_bit().ValueOrDefault())
+      return false;
+    if (has_twelve_bit().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_twelve_bit().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_twelve_bit().ValueOrDefault() &&
+        has_twelve_bit().ValueOrDefault() &&
+        !twelve_bit().Equals(emboss_reserved_local_other.twelve_bit()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_four_bit().ValueOr(false) &&
+        !has_four_bit().ValueOr(false))
+      return false;
+    if (has_four_bit().ValueOr(false) &&
+        !emboss_reserved_local_other.has_four_bit().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_four_bit().ValueOr(false) &&
+        has_four_bit().ValueOr(false) &&
+        !four_bit().UncheckedEquals(emboss_reserved_local_other.four_bit()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_six_bit().ValueOr(false) &&
+        !has_six_bit().ValueOr(false))
+      return false;
+    if (has_six_bit().ValueOr(false) &&
+        !emboss_reserved_local_other.has_six_bit().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_six_bit().ValueOr(false) &&
+        has_six_bit().ValueOr(false) &&
+        !six_bit().UncheckedEquals(emboss_reserved_local_other.six_bit()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_ten_bit().ValueOr(false) &&
+        !has_ten_bit().ValueOr(false))
+      return false;
+    if (has_ten_bit().ValueOr(false) &&
+        !emboss_reserved_local_other.has_ten_bit().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_ten_bit().ValueOr(false) &&
+        has_ten_bit().ValueOr(false) &&
+        !ten_bit().UncheckedEquals(emboss_reserved_local_other.ten_bit()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_twelve_bit().ValueOr(false) &&
+        !has_twelve_bit().ValueOr(false))
+      return false;
+    if (has_twelve_bit().ValueOr(false) &&
+        !emboss_reserved_local_other.has_twelve_bit().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_twelve_bit().ValueOr(false) &&
+        has_twelve_bit().ValueOr(false) &&
+        !twelve_bit().UncheckedEquals(emboss_reserved_local_other.twelve_bit()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "four_bit") {
+        if (!four_bit().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "six_bit") {
+        if (!six_bit().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "ten_bit") {
+        if (!ten_bit().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "twelve_bit") {
+        if (!twelve_bit().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_four_bit().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          four_bit().IsAggregate() || four_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("four_bit: ");
+        four_bit().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !four_bit().IsAggregate() && !four_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# four_bit: UNREADABLE\n");
+      }
+    }
+
+    if (has_six_bit().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          six_bit().IsAggregate() || six_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("six_bit: ");
+        six_bit().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !six_bit().IsAggregate() && !six_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# six_bit: UNREADABLE\n");
+      }
+    }
+
+    if (has_ten_bit().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          ten_bit().IsAggregate() || ten_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("ten_bit: ");
+        ten_bit().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !ten_bit().IsAggregate() && !ten_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# ten_bit: UNREADABLE\n");
+      }
+    }
+
+    if (has_twelve_bit().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          twelve_bit().IsAggregate() || twelve_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("twelve_bit: ");
+        twelve_bit().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !twelve_bit().IsAggregate() && !twelve_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# twelve_bit: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ four_bit() const;
+  ::emboss::support::Maybe<bool> has_four_bit() const;
+
+ public:
+  typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<6, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 4>>
+
+ six_bit() const;
+  ::emboss::support::Maybe<bool> has_six_bit() const;
+
+ public:
+  typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<10, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 10>>
+
+ ten_bit() const;
+  ::emboss::support::Maybe<bool> has_ten_bit() const;
+
+ public:
+  typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<12, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 20>>
+
+ twelve_bit() const;
+  ::emboss::support::Maybe<bool> has_twelve_bit() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView IntrinsicSizeInBits() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBitsView() {}
+    EmbossReservedDollarVirtualMaxSizeInBitsView(const EmbossReservedDollarVirtualMaxSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView(EmbossReservedDollarVirtualMaxSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(const EmbossReservedDollarVirtualMaxSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(EmbossReservedDollarVirtualMaxSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBitsView MaxSizeInBits() {
+    return EmbossReservedDollarVirtualMaxSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBitsView() {}
+    EmbossReservedDollarVirtualMinSizeInBitsView(const EmbossReservedDollarVirtualMinSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView(EmbossReservedDollarVirtualMinSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(const EmbossReservedDollarVirtualMinSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(EmbossReservedDollarVirtualMinSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBitsView MinSizeInBits() {
+    return EmbossReservedDollarVirtualMinSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericEmbossReservedAnonymousField1View;
+};
+using EmbossReservedAnonymousField1View =
+    GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using EmbossReservedAnonymousField1Writer =
+    GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View<
+    GenericEmbossReservedAnonymousField1View<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericEmbossReservedAnonymousField1View<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeEmbossReservedAnonymousField1View( T &&emboss_reserved_local_arg) {
+  return GenericEmbossReservedAnonymousField1View<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeEmbossReservedAnonymousField1View( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericEmbossReservedAnonymousField1View<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedEmbossReservedAnonymousField1View(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericEmbossReservedAnonymousField1View<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+}  // namespace BcdSizes
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericBcdSizesView;
+
+template <class Storage>
+class GenericBcdSizesView final {
+ public:
+  GenericBcdSizesView() : backing_() {}
+  explicit GenericBcdSizesView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericBcdSizesView(
+      const GenericBcdSizesView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericBcdSizesView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericBcdSizesView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericBcdSizesView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericBcdSizesView<Storage> &operator=(
+      const GenericBcdSizesView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_one_byte().Known()) return false;
+    if (has_one_byte().ValueOrDefault() && !one_byte().Ok()) return false;
+
+
+    if (!has_two_byte().Known()) return false;
+    if (has_two_byte().ValueOrDefault() && !two_byte().Ok()) return false;
+
+
+    if (!has_three_byte().Known()) return false;
+    if (has_three_byte().ValueOrDefault() && !three_byte().Ok()) return false;
+
+
+    if (!has_four_byte().Known()) return false;
+    if (has_four_byte().ValueOrDefault() && !four_byte().Ok()) return false;
+
+
+    if (!has_five_byte().Known()) return false;
+    if (has_five_byte().ValueOrDefault() && !five_byte().Ok()) return false;
+
+
+    if (!has_six_byte().Known()) return false;
+    if (has_six_byte().ValueOrDefault() && !six_byte().Ok()) return false;
+
+
+    if (!has_seven_byte().Known()) return false;
+    if (has_seven_byte().ValueOrDefault() && !seven_byte().Ok()) return false;
+
+
+    if (!has_eight_byte().Known()) return false;
+    if (has_eight_byte().ValueOrDefault() && !eight_byte().Ok()) return false;
+
+
+    if (!has_emboss_reserved_anonymous_field_1().Known()) return false;
+    if (has_emboss_reserved_anonymous_field_1().ValueOrDefault() && !emboss_reserved_anonymous_field_1().Ok()) return false;
+
+
+    if (!has_four_bit().Known()) return false;
+    if (has_four_bit().ValueOrDefault() && !four_bit().Ok()) return false;
+
+
+    if (!has_six_bit().Known()) return false;
+    if (has_six_bit().ValueOrDefault() && !six_bit().Ok()) return false;
+
+
+    if (!has_ten_bit().Known()) return false;
+    if (has_ten_bit().ValueOrDefault() && !ten_bit().Ok()) return false;
+
+
+    if (!has_twelve_bit().Known()) return false;
+    if (has_twelve_bit().ValueOrDefault() && !twelve_bit().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericBcdSizesView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_one_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_one_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOrDefault() &&
+        !has_one_byte().ValueOrDefault())
+      return false;
+    if (has_one_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_one_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOrDefault() &&
+        has_one_byte().ValueOrDefault() &&
+        !one_byte().Equals(emboss_reserved_local_other.one_byte()))
+      return false;
+
+
+
+    if (!has_two_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_two_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOrDefault() &&
+        !has_two_byte().ValueOrDefault())
+      return false;
+    if (has_two_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_two_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOrDefault() &&
+        has_two_byte().ValueOrDefault() &&
+        !two_byte().Equals(emboss_reserved_local_other.two_byte()))
+      return false;
+
+
+
+    if (!has_three_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_three_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOrDefault() &&
+        !has_three_byte().ValueOrDefault())
+      return false;
+    if (has_three_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_three_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOrDefault() &&
+        has_three_byte().ValueOrDefault() &&
+        !three_byte().Equals(emboss_reserved_local_other.three_byte()))
+      return false;
+
+
+
+    if (!has_four_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_four_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOrDefault() &&
+        !has_four_byte().ValueOrDefault())
+      return false;
+    if (has_four_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_four_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOrDefault() &&
+        has_four_byte().ValueOrDefault() &&
+        !four_byte().Equals(emboss_reserved_local_other.four_byte()))
+      return false;
+
+
+
+    if (!has_five_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_five_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOrDefault() &&
+        !has_five_byte().ValueOrDefault())
+      return false;
+    if (has_five_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_five_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOrDefault() &&
+        has_five_byte().ValueOrDefault() &&
+        !five_byte().Equals(emboss_reserved_local_other.five_byte()))
+      return false;
+
+
+
+    if (!has_six_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_six_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOrDefault() &&
+        !has_six_byte().ValueOrDefault())
+      return false;
+    if (has_six_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_six_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOrDefault() &&
+        has_six_byte().ValueOrDefault() &&
+        !six_byte().Equals(emboss_reserved_local_other.six_byte()))
+      return false;
+
+
+
+    if (!has_seven_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_seven_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOrDefault() &&
+        !has_seven_byte().ValueOrDefault())
+      return false;
+    if (has_seven_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_seven_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOrDefault() &&
+        has_seven_byte().ValueOrDefault() &&
+        !seven_byte().Equals(emboss_reserved_local_other.seven_byte()))
+      return false;
+
+
+
+    if (!has_eight_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_eight_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOrDefault() &&
+        !has_eight_byte().ValueOrDefault())
+      return false;
+    if (has_eight_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_eight_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOrDefault() &&
+        has_eight_byte().ValueOrDefault() &&
+        !eight_byte().Equals(emboss_reserved_local_other.eight_byte()))
+      return false;
+
+
+
+    if (!has_emboss_reserved_anonymous_field_1().Known()) return false;
+    if (!emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().Known()) return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        !has_emboss_reserved_anonymous_field_1().ValueOrDefault())
+      return false;
+    if (has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        !emboss_reserved_anonymous_field_1().Equals(emboss_reserved_local_other.emboss_reserved_anonymous_field_1()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericBcdSizesView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_one_byte().ValueOr(false) &&
+        !has_one_byte().ValueOr(false))
+      return false;
+    if (has_one_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_one_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOr(false) &&
+        has_one_byte().ValueOr(false) &&
+        !one_byte().UncheckedEquals(emboss_reserved_local_other.one_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOr(false) &&
+        !has_two_byte().ValueOr(false))
+      return false;
+    if (has_two_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_two_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOr(false) &&
+        has_two_byte().ValueOr(false) &&
+        !two_byte().UncheckedEquals(emboss_reserved_local_other.two_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOr(false) &&
+        !has_three_byte().ValueOr(false))
+      return false;
+    if (has_three_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_three_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOr(false) &&
+        has_three_byte().ValueOr(false) &&
+        !three_byte().UncheckedEquals(emboss_reserved_local_other.three_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOr(false) &&
+        !has_four_byte().ValueOr(false))
+      return false;
+    if (has_four_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_four_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOr(false) &&
+        has_four_byte().ValueOr(false) &&
+        !four_byte().UncheckedEquals(emboss_reserved_local_other.four_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOr(false) &&
+        !has_five_byte().ValueOr(false))
+      return false;
+    if (has_five_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_five_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOr(false) &&
+        has_five_byte().ValueOr(false) &&
+        !five_byte().UncheckedEquals(emboss_reserved_local_other.five_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOr(false) &&
+        !has_six_byte().ValueOr(false))
+      return false;
+    if (has_six_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_six_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOr(false) &&
+        has_six_byte().ValueOr(false) &&
+        !six_byte().UncheckedEquals(emboss_reserved_local_other.six_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOr(false) &&
+        !has_seven_byte().ValueOr(false))
+      return false;
+    if (has_seven_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_seven_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOr(false) &&
+        has_seven_byte().ValueOr(false) &&
+        !seven_byte().UncheckedEquals(emboss_reserved_local_other.seven_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOr(false) &&
+        !has_eight_byte().ValueOr(false))
+      return false;
+    if (has_eight_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_eight_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOr(false) &&
+        has_eight_byte().ValueOr(false) &&
+        !eight_byte().UncheckedEquals(emboss_reserved_local_other.eight_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        !has_emboss_reserved_anonymous_field_1().ValueOr(false))
+      return false;
+    if (has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        !emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        !emboss_reserved_anonymous_field_1().UncheckedEquals(emboss_reserved_local_other.emboss_reserved_anonymous_field_1()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericBcdSizesView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericBcdSizesView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericBcdSizesView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "one_byte") {
+        if (!one_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "two_byte") {
+        if (!two_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "three_byte") {
+        if (!three_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "four_byte") {
+        if (!four_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "five_byte") {
+        if (!five_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "six_byte") {
+        if (!six_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "seven_byte") {
+        if (!seven_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "eight_byte") {
+        if (!eight_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "four_bit") {
+        if (!four_bit().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "six_bit") {
+        if (!six_bit().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "ten_bit") {
+        if (!ten_bit().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "twelve_bit") {
+        if (!twelve_bit().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_one_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          one_byte().IsAggregate() || one_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("one_byte: ");
+        one_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !one_byte().IsAggregate() && !one_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# one_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_two_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          two_byte().IsAggregate() || two_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("two_byte: ");
+        two_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !two_byte().IsAggregate() && !two_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# two_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_three_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          three_byte().IsAggregate() || three_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("three_byte: ");
+        three_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !three_byte().IsAggregate() && !three_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# three_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_four_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          four_byte().IsAggregate() || four_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("four_byte: ");
+        four_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !four_byte().IsAggregate() && !four_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# four_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_five_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          five_byte().IsAggregate() || five_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("five_byte: ");
+        five_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !five_byte().IsAggregate() && !five_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# five_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_six_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          six_byte().IsAggregate() || six_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("six_byte: ");
+        six_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !six_byte().IsAggregate() && !six_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# six_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_seven_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          seven_byte().IsAggregate() || seven_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("seven_byte: ");
+        seven_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !seven_byte().IsAggregate() && !seven_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# seven_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_eight_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          eight_byte().IsAggregate() || eight_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("eight_byte: ");
+        eight_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !eight_byte().IsAggregate() && !eight_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# eight_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_four_bit().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          four_bit().IsAggregate() || four_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("four_bit: ");
+        four_bit().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !four_bit().IsAggregate() && !four_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# four_bit: UNREADABLE\n");
+      }
+    }
+
+    if (has_six_bit().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          six_bit().IsAggregate() || six_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("six_bit: ");
+        six_bit().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !six_bit().IsAggregate() && !six_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# six_bit: UNREADABLE\n");
+      }
+    }
+
+    if (has_ten_bit().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          ten_bit().IsAggregate() || ten_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("ten_bit: ");
+        ten_bit().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !ten_bit().IsAggregate() && !ten_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# ten_bit: UNREADABLE\n");
+      }
+    }
+
+    if (has_twelve_bit().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          twelve_bit().IsAggregate() || twelve_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("twelve_bit: ");
+        twelve_bit().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !twelve_bit().IsAggregate() && !twelve_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# twelve_bit: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ one_byte() const;
+  ::emboss::support::Maybe<bool> has_one_byte() const;
+
+ public:
+  typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+ two_byte() const;
+  ::emboss::support::Maybe<bool> has_two_byte() const;
+
+ public:
+  typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+ three_byte() const;
+  ::emboss::support::Maybe<bool> has_three_byte() const;
+
+ public:
+  typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+ four_byte() const;
+  ::emboss::support::Maybe<bool> has_four_byte() const;
+
+ public:
+  typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 40>>
+
+ five_byte() const;
+  ::emboss::support::Maybe<bool> has_five_byte() const;
+
+ public:
+  typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 15>>, 48>>
+
+ six_byte() const;
+  ::emboss::support::Maybe<bool> has_six_byte() const;
+
+ public:
+  typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 56>>
+
+ seven_byte() const;
+  ::emboss::support::Maybe<bool> has_seven_byte() const;
+
+ public:
+  typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 28>>, 64>>
+
+ eight_byte() const;
+  ::emboss::support::Maybe<bool> has_eight_byte() const;
+
+ private:
+  typename ::emboss::test::BcdSizes::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 36>>, 32>>
+
+ emboss_reserved_anonymous_field_1() const;
+  ::emboss::support::Maybe<bool> has_emboss_reserved_anonymous_field_1() const;
+
+ public:
+  auto four_bit() const -> decltype(this->emboss_reserved_anonymous_field_1().four_bit()) {
+   return has_four_bit().ValueOrDefault() ? emboss_reserved_anonymous_field_1().four_bit()
+                                          : decltype(this->emboss_reserved_anonymous_field_1().four_bit())();
+  }
+  ::emboss::support::Maybe<bool> has_four_bit() const;
+
+ public:
+  auto six_bit() const -> decltype(this->emboss_reserved_anonymous_field_1().six_bit()) {
+   return has_six_bit().ValueOrDefault() ? emboss_reserved_anonymous_field_1().six_bit()
+                                          : decltype(this->emboss_reserved_anonymous_field_1().six_bit())();
+  }
+  ::emboss::support::Maybe<bool> has_six_bit() const;
+
+ public:
+  auto ten_bit() const -> decltype(this->emboss_reserved_anonymous_field_1().ten_bit()) {
+   return has_ten_bit().ValueOrDefault() ? emboss_reserved_anonymous_field_1().ten_bit()
+                                          : decltype(this->emboss_reserved_anonymous_field_1().ten_bit())();
+  }
+  ::emboss::support::Maybe<bool> has_ten_bit() const;
+
+ public:
+  auto twelve_bit() const -> decltype(this->emboss_reserved_anonymous_field_1().twelve_bit()) {
+   return has_twelve_bit().ValueOrDefault() ? emboss_reserved_anonymous_field_1().twelve_bit()
+                                          : decltype(this->emboss_reserved_anonymous_field_1().twelve_bit())();
+  }
+  ::emboss::support::Maybe<bool> has_twelve_bit() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericBcdSizesView;
+};
+using BcdSizesView =
+    GenericBcdSizesView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using BcdSizesWriter =
+    GenericBcdSizesView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericBcdSizesView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericBcdSizesView<
+    GenericBcdSizesView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericBcdSizesView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeBcdSizesView( T &&emboss_reserved_local_arg) {
+  return GenericBcdSizesView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericBcdSizesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeBcdSizesView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericBcdSizesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericBcdSizesView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedBcdSizesView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericBcdSizesView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+namespace BcdBigEndian {
+
+}  // namespace BcdBigEndian
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericBcdBigEndianView;
+
+template <class Storage>
+class GenericBcdBigEndianView final {
+ public:
+  GenericBcdBigEndianView() : backing_() {}
+  explicit GenericBcdBigEndianView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericBcdBigEndianView(
+      const GenericBcdBigEndianView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericBcdBigEndianView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericBcdBigEndianView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericBcdBigEndianView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericBcdBigEndianView<Storage> &operator=(
+      const GenericBcdBigEndianView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_four_byte().Known()) return false;
+    if (has_four_byte().ValueOrDefault() && !four_byte().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericBcdBigEndianView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_four_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_four_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOrDefault() &&
+        !has_four_byte().ValueOrDefault())
+      return false;
+    if (has_four_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_four_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOrDefault() &&
+        has_four_byte().ValueOrDefault() &&
+        !four_byte().Equals(emboss_reserved_local_other.four_byte()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericBcdBigEndianView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_four_byte().ValueOr(false) &&
+        !has_four_byte().ValueOr(false))
+      return false;
+    if (has_four_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_four_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOr(false) &&
+        has_four_byte().ValueOr(false) &&
+        !four_byte().UncheckedEquals(emboss_reserved_local_other.four_byte()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericBcdBigEndianView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericBcdBigEndianView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericBcdBigEndianView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "four_byte") {
+        if (!four_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_four_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          four_byte().IsAggregate() || four_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("four_byte: ");
+        four_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !four_byte().IsAggregate() && !four_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# four_byte: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ four_byte() const;
+  ::emboss::support::Maybe<bool> has_four_byte() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericBcdBigEndianView;
+};
+using BcdBigEndianView =
+    GenericBcdBigEndianView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using BcdBigEndianWriter =
+    GenericBcdBigEndianView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericBcdBigEndianView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericBcdBigEndianView<
+    GenericBcdBigEndianView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericBcdBigEndianView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeBcdBigEndianView( T &&emboss_reserved_local_arg) {
+  return GenericBcdBigEndianView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericBcdBigEndianView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeBcdBigEndianView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericBcdBigEndianView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericBcdBigEndianView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedBcdBigEndianView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericBcdBigEndianView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace BcdSizes {
+namespace EmbossReservedAnonymousField1 {
+
+}  // namespace EmbossReservedAnonymousField1
+
+
+template <class Storage>
+inline typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericEmbossReservedAnonymousField1View<Storage>::four_bit()
+    const {
+
+  if ( has_four_bit().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField1View<Storage>::has_four_bit() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<6, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 4>>
+
+ GenericEmbossReservedAnonymousField1View<Storage>::six_bit()
+    const {
+
+  if ( has_six_bit().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<6, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 4>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   4>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<6, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 4>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField1View<Storage>::has_six_bit() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<10, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 10>>
+
+ GenericEmbossReservedAnonymousField1View<Storage>::ten_bit()
+    const {
+
+  if ( has_ten_bit().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<10, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 10>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   10>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<10, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 10>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField1View<Storage>::has_ten_bit() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<12, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 20>>
+
+ GenericEmbossReservedAnonymousField1View<Storage>::twelve_bit()
+    const {
+
+  if ( has_twelve_bit().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(12LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(20LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<12, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 20>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   20>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<12, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 20>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField1View<Storage>::has_twelve_bit() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace EmbossReservedAnonymousField1 {
+inline constexpr ::std::int32_t IntrinsicSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(32LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField1
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField1::IntrinsicSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField1::IntrinsicSizeInBits();
+}
+
+namespace EmbossReservedAnonymousField1 {
+inline constexpr ::std::int32_t MaxSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(32LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField1
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField1::MaxSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField1::MaxSizeInBits();
+}
+
+namespace EmbossReservedAnonymousField1 {
+inline constexpr ::std::int32_t MinSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(32LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField1
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField1::MinSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField1::MinSizeInBits();
+}
+
+}  // namespace BcdSizes
+
+
+template <class Storage>
+inline typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericBcdSizesView<Storage>::one_byte()
+    const {
+
+  if ( has_one_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBcdSizesView<Storage>::has_one_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+ GenericBcdSizesView<Storage>::two_byte()
+    const {
+
+  if ( has_two_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBcdSizesView<Storage>::has_two_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+ GenericBcdSizesView<Storage>::three_byte()
+    const {
+
+  if ( has_three_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   3>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBcdSizesView<Storage>::has_three_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+ GenericBcdSizesView<Storage>::four_byte()
+    const {
+
+  if ( has_four_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   6>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBcdSizesView<Storage>::has_four_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 40>>
+
+ GenericBcdSizesView<Storage>::five_byte()
+    const {
+
+  if ( has_five_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 40>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   10>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 40>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBcdSizesView<Storage>::has_five_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 15>>, 48>>
+
+ GenericBcdSizesView<Storage>::six_byte()
+    const {
+
+  if ( has_six_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(15LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 15>>, 48>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   15>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 15>>, 48>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBcdSizesView<Storage>::has_six_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 56>>
+
+ GenericBcdSizesView<Storage>::seven_byte()
+    const {
+
+  if ( has_seven_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(7LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(21LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 56>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   21>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 56>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBcdSizesView<Storage>::has_seven_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 28>>, 64>>
+
+ GenericBcdSizesView<Storage>::eight_byte()
+    const {
+
+  if ( has_eight_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(28LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 28>>, 64>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   28>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 28>>, 64>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBcdSizesView<Storage>::has_eight_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::BcdSizes::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 36>>, 32>>
+
+ GenericBcdSizesView<Storage>::emboss_reserved_anonymous_field_1()
+    const {
+
+  if ( has_emboss_reserved_anonymous_field_1().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(36LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::BcdSizes::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 36>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   36>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::BcdSizes::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 36>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBcdSizesView<Storage>::has_emboss_reserved_anonymous_field_1() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBcdSizesView<Storage>::has_four_bit() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBcdSizesView<Storage>::has_six_bit() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBcdSizesView<Storage>::has_ten_bit() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBcdSizesView<Storage>::has_twelve_bit() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+namespace BcdSizes {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(40LL)).ValueOrDefault();
+}
+}  // namespace BcdSizes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBcdSizesView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return BcdSizes::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBcdSizesView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return BcdSizes::IntrinsicSizeInBytes();
+}
+
+namespace BcdSizes {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(40LL)).ValueOrDefault();
+}
+}  // namespace BcdSizes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBcdSizesView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return BcdSizes::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBcdSizesView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return BcdSizes::MaxSizeInBytes();
+}
+
+namespace BcdSizes {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(40LL)).ValueOrDefault();
+}
+}  // namespace BcdSizes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBcdSizesView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return BcdSizes::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBcdSizesView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return BcdSizes::MinSizeInBytes();
+}
+namespace BcdBigEndian {
+
+}  // namespace BcdBigEndian
+
+
+template <class Storage>
+inline typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ GenericBcdBigEndianView<Storage>::four_byte()
+    const {
+
+  if ( has_four_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBcdBigEndianView<Storage>::has_four_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace BcdBigEndian {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace BcdBigEndian
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBcdBigEndianView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return BcdBigEndian::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBcdBigEndianView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return BcdBigEndian::IntrinsicSizeInBytes();
+}
+
+namespace BcdBigEndian {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace BcdBigEndian
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBcdBigEndianView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return BcdBigEndian::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBcdBigEndianView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return BcdBigEndian::MaxSizeInBytes();
+}
+
+namespace BcdBigEndian {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace BcdBigEndian
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBcdBigEndianView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return BcdBigEndian::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBcdBigEndianView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return BcdBigEndian::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_BCD_EMB_H_
+
diff --git a/testdata/golden_cpp/bits.emb.h b/testdata/golden_cpp/bits.emb.h
new file mode 100644
index 0000000..e6f29da
--- /dev/null
+++ b/testdata/golden_cpp/bits.emb.h
@@ -0,0 +1,5523 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_BITS_EMB_H_
+#define TESTDATA_BITS_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace OneByte {
+
+}  // namespace OneByte
+
+
+template <class Storage>
+class GenericOneByteView;
+
+namespace FourByte {
+namespace TwoByteWithGaps {
+
+}  // namespace TwoByteWithGaps
+
+
+template <class Storage>
+class GenericTwoByteWithGapsView;
+
+
+}  // namespace FourByte
+
+
+template <class Storage>
+class GenericFourByteView;
+
+namespace ArrayInBits {
+
+}  // namespace ArrayInBits
+
+
+template <class Storage>
+class GenericArrayInBitsView;
+
+namespace ArrayInBitsInStruct {
+
+}  // namespace ArrayInBitsInStruct
+
+
+template <class Storage>
+class GenericArrayInBitsInStructView;
+
+namespace StructOfBits {
+
+}  // namespace StructOfBits
+
+
+template <class Storage>
+class GenericStructOfBitsView;
+
+namespace BitArray {
+
+}  // namespace BitArray
+
+
+template <class Storage>
+class GenericBitArrayView;
+
+
+
+
+
+
+
+
+
+namespace OneByte {
+
+}  // namespace OneByte
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericOneByteView;
+
+template <class Storage>
+class GenericOneByteView final {
+ public:
+  GenericOneByteView() : backing_() {}
+  explicit GenericOneByteView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericOneByteView(
+      const GenericOneByteView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericOneByteView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericOneByteView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericOneByteView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericOneByteView<Storage> &operator=(
+      const GenericOneByteView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_high_bit().Known()) return false;
+    if (has_high_bit().ValueOrDefault() && !high_bit().Ok()) return false;
+
+
+    if (!has_less_high_bit().Known()) return false;
+    if (has_less_high_bit().ValueOrDefault() && !less_high_bit().Ok()) return false;
+
+
+    if (!has_mid_nibble().Known()) return false;
+    if (has_mid_nibble().ValueOrDefault() && !mid_nibble().Ok()) return false;
+
+
+    if (!has_less_low_bit().Known()) return false;
+    if (has_less_low_bit().ValueOrDefault() && !less_low_bit().Ok()) return false;
+
+
+    if (!has_low_bit().Known()) return false;
+    if (has_low_bit().ValueOrDefault() && !low_bit().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBits().Known()) return false;
+    if (has_IntrinsicSizeInBits().ValueOrDefault() && !IntrinsicSizeInBits().Ok()) return false;
+
+
+    if (!has_MaxSizeInBits().Known()) return false;
+    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok()) return false;
+
+
+    if (!has_MinSizeInBits().Known()) return false;
+    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBits().Ok() &&
+           backing_.SizeInBits() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBits().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBits() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBits().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBits().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericOneByteView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_high_bit().Known()) return false;
+    if (!emboss_reserved_local_other.has_high_bit().Known()) return false;
+
+    if (emboss_reserved_local_other.has_high_bit().ValueOrDefault() &&
+        !has_high_bit().ValueOrDefault())
+      return false;
+    if (has_high_bit().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_high_bit().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_high_bit().ValueOrDefault() &&
+        has_high_bit().ValueOrDefault() &&
+        !high_bit().Equals(emboss_reserved_local_other.high_bit()))
+      return false;
+
+
+
+    if (!has_less_high_bit().Known()) return false;
+    if (!emboss_reserved_local_other.has_less_high_bit().Known()) return false;
+
+    if (emboss_reserved_local_other.has_less_high_bit().ValueOrDefault() &&
+        !has_less_high_bit().ValueOrDefault())
+      return false;
+    if (has_less_high_bit().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_less_high_bit().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_less_high_bit().ValueOrDefault() &&
+        has_less_high_bit().ValueOrDefault() &&
+        !less_high_bit().Equals(emboss_reserved_local_other.less_high_bit()))
+      return false;
+
+
+
+    if (!has_mid_nibble().Known()) return false;
+    if (!emboss_reserved_local_other.has_mid_nibble().Known()) return false;
+
+    if (emboss_reserved_local_other.has_mid_nibble().ValueOrDefault() &&
+        !has_mid_nibble().ValueOrDefault())
+      return false;
+    if (has_mid_nibble().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_mid_nibble().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_mid_nibble().ValueOrDefault() &&
+        has_mid_nibble().ValueOrDefault() &&
+        !mid_nibble().Equals(emboss_reserved_local_other.mid_nibble()))
+      return false;
+
+
+
+    if (!has_less_low_bit().Known()) return false;
+    if (!emboss_reserved_local_other.has_less_low_bit().Known()) return false;
+
+    if (emboss_reserved_local_other.has_less_low_bit().ValueOrDefault() &&
+        !has_less_low_bit().ValueOrDefault())
+      return false;
+    if (has_less_low_bit().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_less_low_bit().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_less_low_bit().ValueOrDefault() &&
+        has_less_low_bit().ValueOrDefault() &&
+        !less_low_bit().Equals(emboss_reserved_local_other.less_low_bit()))
+      return false;
+
+
+
+    if (!has_low_bit().Known()) return false;
+    if (!emboss_reserved_local_other.has_low_bit().Known()) return false;
+
+    if (emboss_reserved_local_other.has_low_bit().ValueOrDefault() &&
+        !has_low_bit().ValueOrDefault())
+      return false;
+    if (has_low_bit().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_low_bit().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_low_bit().ValueOrDefault() &&
+        has_low_bit().ValueOrDefault() &&
+        !low_bit().Equals(emboss_reserved_local_other.low_bit()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericOneByteView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_high_bit().ValueOr(false) &&
+        !has_high_bit().ValueOr(false))
+      return false;
+    if (has_high_bit().ValueOr(false) &&
+        !emboss_reserved_local_other.has_high_bit().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_high_bit().ValueOr(false) &&
+        has_high_bit().ValueOr(false) &&
+        !high_bit().UncheckedEquals(emboss_reserved_local_other.high_bit()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_less_high_bit().ValueOr(false) &&
+        !has_less_high_bit().ValueOr(false))
+      return false;
+    if (has_less_high_bit().ValueOr(false) &&
+        !emboss_reserved_local_other.has_less_high_bit().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_less_high_bit().ValueOr(false) &&
+        has_less_high_bit().ValueOr(false) &&
+        !less_high_bit().UncheckedEquals(emboss_reserved_local_other.less_high_bit()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_mid_nibble().ValueOr(false) &&
+        !has_mid_nibble().ValueOr(false))
+      return false;
+    if (has_mid_nibble().ValueOr(false) &&
+        !emboss_reserved_local_other.has_mid_nibble().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_mid_nibble().ValueOr(false) &&
+        has_mid_nibble().ValueOr(false) &&
+        !mid_nibble().UncheckedEquals(emboss_reserved_local_other.mid_nibble()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_less_low_bit().ValueOr(false) &&
+        !has_less_low_bit().ValueOr(false))
+      return false;
+    if (has_less_low_bit().ValueOr(false) &&
+        !emboss_reserved_local_other.has_less_low_bit().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_less_low_bit().ValueOr(false) &&
+        has_less_low_bit().ValueOr(false) &&
+        !less_low_bit().UncheckedEquals(emboss_reserved_local_other.less_low_bit()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_low_bit().ValueOr(false) &&
+        !has_low_bit().ValueOr(false))
+      return false;
+    if (has_low_bit().ValueOr(false) &&
+        !emboss_reserved_local_other.has_low_bit().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_low_bit().ValueOr(false) &&
+        has_low_bit().ValueOr(false) &&
+        !low_bit().UncheckedEquals(emboss_reserved_local_other.low_bit()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericOneByteView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericOneByteView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericOneByteView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "high_bit") {
+        if (!high_bit().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "less_high_bit") {
+        if (!less_high_bit().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "mid_nibble") {
+        if (!mid_nibble().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "less_low_bit") {
+        if (!less_low_bit().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "low_bit") {
+        if (!low_bit().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_high_bit().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          high_bit().IsAggregate() || high_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("high_bit: ");
+        high_bit().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !high_bit().IsAggregate() && !high_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# high_bit: UNREADABLE\n");
+      }
+    }
+
+    if (has_less_high_bit().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          less_high_bit().IsAggregate() || less_high_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("less_high_bit: ");
+        less_high_bit().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !less_high_bit().IsAggregate() && !less_high_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# less_high_bit: UNREADABLE\n");
+      }
+    }
+
+    if (has_mid_nibble().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          mid_nibble().IsAggregate() || mid_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("mid_nibble: ");
+        mid_nibble().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !mid_nibble().IsAggregate() && !mid_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# mid_nibble: UNREADABLE\n");
+      }
+    }
+
+    if (has_less_low_bit().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          less_low_bit().IsAggregate() || less_low_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("less_low_bit: ");
+        less_low_bit().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !less_low_bit().IsAggregate() && !less_low_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# less_low_bit: UNREADABLE\n");
+      }
+    }
+
+    if (has_low_bit().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          low_bit().IsAggregate() || low_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("low_bit: ");
+        low_bit().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !low_bit().IsAggregate() && !low_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# low_bit: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 7>>
+
+ high_bit() const;
+  ::emboss::support::Maybe<bool> has_high_bit() const;
+
+ public:
+  typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 6>>
+
+ less_high_bit() const;
+  ::emboss::support::Maybe<bool> has_less_high_bit() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 2>>
+
+ mid_nibble() const;
+  ::emboss::support::Maybe<bool> has_mid_nibble() const;
+
+ public:
+  typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 1>>
+
+ less_low_bit() const;
+  ::emboss::support::Maybe<bool> has_less_low_bit() const;
+
+ public:
+  typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ low_bit() const;
+  ::emboss::support::Maybe<bool> has_low_bit() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView IntrinsicSizeInBits() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBitsView() {}
+    EmbossReservedDollarVirtualMaxSizeInBitsView(const EmbossReservedDollarVirtualMaxSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView(EmbossReservedDollarVirtualMaxSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(const EmbossReservedDollarVirtualMaxSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(EmbossReservedDollarVirtualMaxSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBitsView MaxSizeInBits() {
+    return EmbossReservedDollarVirtualMaxSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBitsView() {}
+    EmbossReservedDollarVirtualMinSizeInBitsView(const EmbossReservedDollarVirtualMinSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView(EmbossReservedDollarVirtualMinSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(const EmbossReservedDollarVirtualMinSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(EmbossReservedDollarVirtualMinSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBitsView MinSizeInBits() {
+    return EmbossReservedDollarVirtualMinSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericOneByteView;
+};
+using OneByteView =
+    GenericOneByteView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using OneByteWriter =
+    GenericOneByteView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericOneByteView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericOneByteView<
+    GenericOneByteView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericOneByteView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeOneByteView( T &&emboss_reserved_local_arg) {
+  return GenericOneByteView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericOneByteView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeOneByteView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericOneByteView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericOneByteView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedOneByteView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericOneByteView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+namespace FourByte {
+struct EmbossReservedValidatorForRawLowNibble {
+  template <typename ValueType>
+  static constexpr bool ValueIsOk(ValueType emboss_reserved_local_value) {
+    return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+           (::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), ::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value)), ::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(15LL))))).ValueOrDefault();
+  }
+};
+
+
+}  // namespace FourByte
+
+
+
+
+
+
+namespace FourByte {
+
+
+
+
+
+namespace TwoByteWithGaps {
+
+}  // namespace TwoByteWithGaps
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericTwoByteWithGapsView;
+
+template <class Storage>
+class GenericTwoByteWithGapsView final {
+ public:
+  GenericTwoByteWithGapsView() : backing_() {}
+  explicit GenericTwoByteWithGapsView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericTwoByteWithGapsView(
+      const GenericTwoByteWithGapsView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericTwoByteWithGapsView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericTwoByteWithGapsView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericTwoByteWithGapsView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericTwoByteWithGapsView<Storage> &operator=(
+      const GenericTwoByteWithGapsView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_high_bit().Known()) return false;
+    if (has_high_bit().ValueOrDefault() && !high_bit().Ok()) return false;
+
+
+    if (!has_mid_nibble().Known()) return false;
+    if (has_mid_nibble().ValueOrDefault() && !mid_nibble().Ok()) return false;
+
+
+    if (!has_low_bit().Known()) return false;
+    if (has_low_bit().ValueOrDefault() && !low_bit().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBits().Known()) return false;
+    if (has_IntrinsicSizeInBits().ValueOrDefault() && !IntrinsicSizeInBits().Ok()) return false;
+
+
+    if (!has_MaxSizeInBits().Known()) return false;
+    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok()) return false;
+
+
+    if (!has_MinSizeInBits().Known()) return false;
+    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBits().Ok() &&
+           backing_.SizeInBits() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBits().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBits() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBits().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBits().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericTwoByteWithGapsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_high_bit().Known()) return false;
+    if (!emboss_reserved_local_other.has_high_bit().Known()) return false;
+
+    if (emboss_reserved_local_other.has_high_bit().ValueOrDefault() &&
+        !has_high_bit().ValueOrDefault())
+      return false;
+    if (has_high_bit().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_high_bit().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_high_bit().ValueOrDefault() &&
+        has_high_bit().ValueOrDefault() &&
+        !high_bit().Equals(emboss_reserved_local_other.high_bit()))
+      return false;
+
+
+
+    if (!has_mid_nibble().Known()) return false;
+    if (!emboss_reserved_local_other.has_mid_nibble().Known()) return false;
+
+    if (emboss_reserved_local_other.has_mid_nibble().ValueOrDefault() &&
+        !has_mid_nibble().ValueOrDefault())
+      return false;
+    if (has_mid_nibble().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_mid_nibble().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_mid_nibble().ValueOrDefault() &&
+        has_mid_nibble().ValueOrDefault() &&
+        !mid_nibble().Equals(emboss_reserved_local_other.mid_nibble()))
+      return false;
+
+
+
+    if (!has_low_bit().Known()) return false;
+    if (!emboss_reserved_local_other.has_low_bit().Known()) return false;
+
+    if (emboss_reserved_local_other.has_low_bit().ValueOrDefault() &&
+        !has_low_bit().ValueOrDefault())
+      return false;
+    if (has_low_bit().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_low_bit().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_low_bit().ValueOrDefault() &&
+        has_low_bit().ValueOrDefault() &&
+        !low_bit().Equals(emboss_reserved_local_other.low_bit()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericTwoByteWithGapsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_high_bit().ValueOr(false) &&
+        !has_high_bit().ValueOr(false))
+      return false;
+    if (has_high_bit().ValueOr(false) &&
+        !emboss_reserved_local_other.has_high_bit().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_high_bit().ValueOr(false) &&
+        has_high_bit().ValueOr(false) &&
+        !high_bit().UncheckedEquals(emboss_reserved_local_other.high_bit()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_mid_nibble().ValueOr(false) &&
+        !has_mid_nibble().ValueOr(false))
+      return false;
+    if (has_mid_nibble().ValueOr(false) &&
+        !emboss_reserved_local_other.has_mid_nibble().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_mid_nibble().ValueOr(false) &&
+        has_mid_nibble().ValueOr(false) &&
+        !mid_nibble().UncheckedEquals(emboss_reserved_local_other.mid_nibble()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_low_bit().ValueOr(false) &&
+        !has_low_bit().ValueOr(false))
+      return false;
+    if (has_low_bit().ValueOr(false) &&
+        !emboss_reserved_local_other.has_low_bit().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_low_bit().ValueOr(false) &&
+        has_low_bit().ValueOr(false) &&
+        !low_bit().UncheckedEquals(emboss_reserved_local_other.low_bit()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericTwoByteWithGapsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericTwoByteWithGapsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericTwoByteWithGapsView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "high_bit") {
+        if (!high_bit().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "mid_nibble") {
+        if (!mid_nibble().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "low_bit") {
+        if (!low_bit().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_high_bit().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          high_bit().IsAggregate() || high_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("high_bit: ");
+        high_bit().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !high_bit().IsAggregate() && !high_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# high_bit: UNREADABLE\n");
+      }
+    }
+
+    if (has_mid_nibble().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          mid_nibble().IsAggregate() || mid_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("mid_nibble: ");
+        mid_nibble().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !mid_nibble().IsAggregate() && !mid_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# mid_nibble: UNREADABLE\n");
+      }
+    }
+
+    if (has_low_bit().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          low_bit().IsAggregate() || low_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("low_bit: ");
+        low_bit().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !low_bit().IsAggregate() && !low_bit().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# low_bit: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 15>>
+
+ high_bit() const;
+  ::emboss::support::Maybe<bool> has_high_bit() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 6>>
+
+ mid_nibble() const;
+  ::emboss::support::Maybe<bool> has_mid_nibble() const;
+
+ public:
+  typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ low_bit() const;
+  ::emboss::support::Maybe<bool> has_low_bit() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView IntrinsicSizeInBits() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBitsView() {}
+    EmbossReservedDollarVirtualMaxSizeInBitsView(const EmbossReservedDollarVirtualMaxSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView(EmbossReservedDollarVirtualMaxSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(const EmbossReservedDollarVirtualMaxSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(EmbossReservedDollarVirtualMaxSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBitsView MaxSizeInBits() {
+    return EmbossReservedDollarVirtualMaxSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBitsView() {}
+    EmbossReservedDollarVirtualMinSizeInBitsView(const EmbossReservedDollarVirtualMinSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView(EmbossReservedDollarVirtualMinSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(const EmbossReservedDollarVirtualMinSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(EmbossReservedDollarVirtualMinSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBitsView MinSizeInBits() {
+    return EmbossReservedDollarVirtualMinSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericTwoByteWithGapsView;
+};
+using TwoByteWithGapsView =
+    GenericTwoByteWithGapsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using TwoByteWithGapsWriter =
+    GenericTwoByteWithGapsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericTwoByteWithGapsView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericTwoByteWithGapsView<
+    GenericTwoByteWithGapsView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericTwoByteWithGapsView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeTwoByteWithGapsView( T &&emboss_reserved_local_arg) {
+  return GenericTwoByteWithGapsView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericTwoByteWithGapsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeTwoByteWithGapsView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericTwoByteWithGapsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericTwoByteWithGapsView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedTwoByteWithGapsView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericTwoByteWithGapsView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+}  // namespace FourByte
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericFourByteView;
+
+template <class Storage>
+class GenericFourByteView final {
+ public:
+  GenericFourByteView() : backing_() {}
+  explicit GenericFourByteView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericFourByteView(
+      const GenericFourByteView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericFourByteView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericFourByteView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericFourByteView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericFourByteView<Storage> &operator=(
+      const GenericFourByteView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_high_nibble().Known()) return false;
+    if (has_high_nibble().ValueOrDefault() && !high_nibble().Ok()) return false;
+
+
+    if (!has_one_byte().Known()) return false;
+    if (has_one_byte().ValueOrDefault() && !one_byte().Ok()) return false;
+
+
+    if (!has_two_byte().Known()) return false;
+    if (has_two_byte().ValueOrDefault() && !two_byte().Ok()) return false;
+
+
+    if (!has_raw_low_nibble().Known()) return false;
+    if (has_raw_low_nibble().ValueOrDefault() && !raw_low_nibble().Ok()) return false;
+
+
+    if (!has_low_nibble().Known()) return false;
+    if (has_low_nibble().ValueOrDefault() && !low_nibble().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBits().Known()) return false;
+    if (has_IntrinsicSizeInBits().ValueOrDefault() && !IntrinsicSizeInBits().Ok()) return false;
+
+
+    if (!has_MaxSizeInBits().Known()) return false;
+    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok()) return false;
+
+
+    if (!has_MinSizeInBits().Known()) return false;
+    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBits().Ok() &&
+           backing_.SizeInBits() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBits().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBits() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBits().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBits().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericFourByteView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_high_nibble().Known()) return false;
+    if (!emboss_reserved_local_other.has_high_nibble().Known()) return false;
+
+    if (emboss_reserved_local_other.has_high_nibble().ValueOrDefault() &&
+        !has_high_nibble().ValueOrDefault())
+      return false;
+    if (has_high_nibble().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_high_nibble().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_high_nibble().ValueOrDefault() &&
+        has_high_nibble().ValueOrDefault() &&
+        !high_nibble().Equals(emboss_reserved_local_other.high_nibble()))
+      return false;
+
+
+
+    if (!has_one_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_one_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOrDefault() &&
+        !has_one_byte().ValueOrDefault())
+      return false;
+    if (has_one_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_one_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOrDefault() &&
+        has_one_byte().ValueOrDefault() &&
+        !one_byte().Equals(emboss_reserved_local_other.one_byte()))
+      return false;
+
+
+
+    if (!has_two_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_two_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOrDefault() &&
+        !has_two_byte().ValueOrDefault())
+      return false;
+    if (has_two_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_two_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOrDefault() &&
+        has_two_byte().ValueOrDefault() &&
+        !two_byte().Equals(emboss_reserved_local_other.two_byte()))
+      return false;
+
+
+
+    if (!has_raw_low_nibble().Known()) return false;
+    if (!emboss_reserved_local_other.has_raw_low_nibble().Known()) return false;
+
+    if (emboss_reserved_local_other.has_raw_low_nibble().ValueOrDefault() &&
+        !has_raw_low_nibble().ValueOrDefault())
+      return false;
+    if (has_raw_low_nibble().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_raw_low_nibble().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_raw_low_nibble().ValueOrDefault() &&
+        has_raw_low_nibble().ValueOrDefault() &&
+        !raw_low_nibble().Equals(emboss_reserved_local_other.raw_low_nibble()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericFourByteView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_high_nibble().ValueOr(false) &&
+        !has_high_nibble().ValueOr(false))
+      return false;
+    if (has_high_nibble().ValueOr(false) &&
+        !emboss_reserved_local_other.has_high_nibble().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_high_nibble().ValueOr(false) &&
+        has_high_nibble().ValueOr(false) &&
+        !high_nibble().UncheckedEquals(emboss_reserved_local_other.high_nibble()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOr(false) &&
+        !has_one_byte().ValueOr(false))
+      return false;
+    if (has_one_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_one_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOr(false) &&
+        has_one_byte().ValueOr(false) &&
+        !one_byte().UncheckedEquals(emboss_reserved_local_other.one_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOr(false) &&
+        !has_two_byte().ValueOr(false))
+      return false;
+    if (has_two_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_two_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOr(false) &&
+        has_two_byte().ValueOr(false) &&
+        !two_byte().UncheckedEquals(emboss_reserved_local_other.two_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_raw_low_nibble().ValueOr(false) &&
+        !has_raw_low_nibble().ValueOr(false))
+      return false;
+    if (has_raw_low_nibble().ValueOr(false) &&
+        !emboss_reserved_local_other.has_raw_low_nibble().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_raw_low_nibble().ValueOr(false) &&
+        has_raw_low_nibble().ValueOr(false) &&
+        !raw_low_nibble().UncheckedEquals(emboss_reserved_local_other.raw_low_nibble()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericFourByteView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericFourByteView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericFourByteView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "high_nibble") {
+        if (!high_nibble().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "one_byte") {
+        if (!one_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "two_byte") {
+        if (!two_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "raw_low_nibble") {
+        if (!raw_low_nibble().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "low_nibble") {
+        if (!low_nibble().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_high_nibble().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          high_nibble().IsAggregate() || high_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("high_nibble: ");
+        high_nibble().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !high_nibble().IsAggregate() && !high_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# high_nibble: UNREADABLE\n");
+      }
+    }
+
+    if (has_one_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          one_byte().IsAggregate() || one_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("one_byte: ");
+        one_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !one_byte().IsAggregate() && !one_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# one_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_two_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          two_byte().IsAggregate() || two_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("two_byte: ");
+        two_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !two_byte().IsAggregate() && !two_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# two_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_raw_low_nibble().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          raw_low_nibble().IsAggregate() || raw_low_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("raw_low_nibble: ");
+        raw_low_nibble().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !raw_low_nibble().IsAggregate() && !raw_low_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# raw_low_nibble: UNREADABLE\n");
+      }
+    }
+
+    if (has_low_nibble().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          low_nibble().IsAggregate() || low_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("low_nibble: ");
+        low_nibble().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !low_nibble().IsAggregate() && !low_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# low_nibble: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 28>>
+
+ high_nibble() const;
+  ::emboss::support::Maybe<bool> has_high_nibble() const;
+
+ public:
+  typename ::emboss::test::GenericOneByteView<typename Storage::template OffsetStorageType</**/0, 20>>
+
+ one_byte() const;
+  ::emboss::support::Maybe<bool> has_one_byte() const;
+
+ public:
+  typename ::emboss::test::FourByte::GenericTwoByteWithGapsView<typename Storage::template OffsetStorageType</**/0, 4>>
+
+ two_byte() const;
+  ::emboss::support::Maybe<bool> has_two_byte() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, FourByte::EmbossReservedValidatorForRawLowNibble>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ raw_low_nibble() const;
+  ::emboss::support::Maybe<bool> has_raw_low_nibble() const;
+
+ public:
+  class EmbossReservedVirtualLowNibbleView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedVirtualLowNibbleView(
+        const GenericFourByteView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualLowNibbleView() = delete;
+    EmbossReservedVirtualLowNibbleView(const EmbossReservedVirtualLowNibbleView &) = default;
+    EmbossReservedVirtualLowNibbleView(EmbossReservedVirtualLowNibbleView &&) = default;
+    EmbossReservedVirtualLowNibbleView &operator=(const EmbossReservedVirtualLowNibbleView &) =
+        default;
+    EmbossReservedVirtualLowNibbleView &operator=(EmbossReservedVirtualLowNibbleView &&) =
+        default;
+    ~EmbossReservedVirtualLowNibbleView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_low_nibble().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+    bool TryToWrite(::std::int32_t emboss_reserved_local_value) {
+      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(100LL)));
+      if (!CouldWriteValue(emboss_reserved_local_value)) return false;
+      return view_.raw_low_nibble().TryToWrite(
+          emboss_reserved_local_maybe_new_value.ValueOrDefault());
+    }
+    void Write(::std::int32_t emboss_reserved_local_value) {
+      const bool result = TryToWrite(emboss_reserved_local_value);
+      (void)result;
+      EMBOSS_CHECK(result);
+    }
+    void UncheckedWrite(::std::int32_t emboss_reserved_local_value) {
+      view_.raw_low_nibble().UncheckedWrite((::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(100LL)))).ValueOrDefault());
+    }
+    bool CouldWriteValue(::std::int32_t emboss_reserved_local_value) {
+      if (!ValueIsOk(emboss_reserved_local_value)) return false;
+      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(100LL)));
+      if (!emboss_reserved_local_maybe_new_value.Known()) return false;
+      return view_.raw_low_nibble().CouldWriteValue(
+          emboss_reserved_local_maybe_new_value.ValueOrDefault());
+    }
+    template <class Stream>
+    bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) {
+      return ::emboss::support::ReadIntegerFromTextStream(
+          this, emboss_reserved_local_stream);
+    }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.raw_low_nibble();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(100LL)));
+
+      return emboss_reserved_local_subexpr_3;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericFourByteView view_;
+  };
+  EmbossReservedVirtualLowNibbleView low_nibble() const;
+  ::emboss::support::Maybe<bool> has_low_nibble() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView IntrinsicSizeInBits() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBitsView() {}
+    EmbossReservedDollarVirtualMaxSizeInBitsView(const EmbossReservedDollarVirtualMaxSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView(EmbossReservedDollarVirtualMaxSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(const EmbossReservedDollarVirtualMaxSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(EmbossReservedDollarVirtualMaxSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBitsView MaxSizeInBits() {
+    return EmbossReservedDollarVirtualMaxSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBitsView() {}
+    EmbossReservedDollarVirtualMinSizeInBitsView(const EmbossReservedDollarVirtualMinSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView(EmbossReservedDollarVirtualMinSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(const EmbossReservedDollarVirtualMinSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(EmbossReservedDollarVirtualMinSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBitsView MinSizeInBits() {
+    return EmbossReservedDollarVirtualMinSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericFourByteView;
+};
+using FourByteView =
+    GenericFourByteView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using FourByteWriter =
+    GenericFourByteView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericFourByteView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericFourByteView<
+    GenericFourByteView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericFourByteView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeFourByteView( T &&emboss_reserved_local_arg) {
+  return GenericFourByteView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericFourByteView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeFourByteView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericFourByteView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericFourByteView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedFourByteView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericFourByteView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace ArrayInBits {
+
+}  // namespace ArrayInBits
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericArrayInBitsView;
+
+template <class Storage>
+class GenericArrayInBitsView final {
+ public:
+  GenericArrayInBitsView() : backing_() {}
+  explicit GenericArrayInBitsView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericArrayInBitsView(
+      const GenericArrayInBitsView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericArrayInBitsView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericArrayInBitsView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericArrayInBitsView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericArrayInBitsView<Storage> &operator=(
+      const GenericArrayInBitsView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_lone_flag().Known()) return false;
+    if (has_lone_flag().ValueOrDefault() && !lone_flag().Ok()) return false;
+
+
+    if (!has_flags().Known()) return false;
+    if (has_flags().ValueOrDefault() && !flags().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBits().Known()) return false;
+    if (has_IntrinsicSizeInBits().ValueOrDefault() && !IntrinsicSizeInBits().Ok()) return false;
+
+
+    if (!has_MaxSizeInBits().Known()) return false;
+    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok()) return false;
+
+
+    if (!has_MinSizeInBits().Known()) return false;
+    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBits().Ok() &&
+           backing_.SizeInBits() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBits().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBits() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBits().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBits().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericArrayInBitsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_lone_flag().Known()) return false;
+    if (!emboss_reserved_local_other.has_lone_flag().Known()) return false;
+
+    if (emboss_reserved_local_other.has_lone_flag().ValueOrDefault() &&
+        !has_lone_flag().ValueOrDefault())
+      return false;
+    if (has_lone_flag().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_lone_flag().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_lone_flag().ValueOrDefault() &&
+        has_lone_flag().ValueOrDefault() &&
+        !lone_flag().Equals(emboss_reserved_local_other.lone_flag()))
+      return false;
+
+
+
+    if (!has_flags().Known()) return false;
+    if (!emboss_reserved_local_other.has_flags().Known()) return false;
+
+    if (emboss_reserved_local_other.has_flags().ValueOrDefault() &&
+        !has_flags().ValueOrDefault())
+      return false;
+    if (has_flags().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_flags().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_flags().ValueOrDefault() &&
+        has_flags().ValueOrDefault() &&
+        !flags().Equals(emboss_reserved_local_other.flags()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericArrayInBitsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_lone_flag().ValueOr(false) &&
+        !has_lone_flag().ValueOr(false))
+      return false;
+    if (has_lone_flag().ValueOr(false) &&
+        !emboss_reserved_local_other.has_lone_flag().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_lone_flag().ValueOr(false) &&
+        has_lone_flag().ValueOr(false) &&
+        !lone_flag().UncheckedEquals(emboss_reserved_local_other.lone_flag()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_flags().ValueOr(false) &&
+        !has_flags().ValueOr(false))
+      return false;
+    if (has_flags().ValueOr(false) &&
+        !emboss_reserved_local_other.has_flags().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_flags().ValueOr(false) &&
+        has_flags().ValueOr(false) &&
+        !flags().UncheckedEquals(emboss_reserved_local_other.flags()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericArrayInBitsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericArrayInBitsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericArrayInBitsView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "lone_flag") {
+        if (!lone_flag().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "flags") {
+        if (!flags().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_lone_flag().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          lone_flag().IsAggregate() || lone_flag().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("lone_flag: ");
+        lone_flag().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !lone_flag().IsAggregate() && !lone_flag().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# lone_flag: UNREADABLE\n");
+      }
+    }
+
+    if (has_flags().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          flags().IsAggregate() || flags().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("flags: ");
+        flags().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !flags().IsAggregate() && !flags().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# flags: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 15>>
+
+ lone_flag() const;
+  ::emboss::support::Maybe<bool> has_lone_flag() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/1, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 1,
+    1 >
+
+ flags() const;
+  ::emboss::support::Maybe<bool> has_flags() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView IntrinsicSizeInBits() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBitsView() {}
+    EmbossReservedDollarVirtualMaxSizeInBitsView(const EmbossReservedDollarVirtualMaxSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView(EmbossReservedDollarVirtualMaxSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(const EmbossReservedDollarVirtualMaxSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(EmbossReservedDollarVirtualMaxSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBitsView MaxSizeInBits() {
+    return EmbossReservedDollarVirtualMaxSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBitsView() {}
+    EmbossReservedDollarVirtualMinSizeInBitsView(const EmbossReservedDollarVirtualMinSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView(EmbossReservedDollarVirtualMinSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(const EmbossReservedDollarVirtualMinSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(EmbossReservedDollarVirtualMinSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBitsView MinSizeInBits() {
+    return EmbossReservedDollarVirtualMinSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericArrayInBitsView;
+};
+using ArrayInBitsView =
+    GenericArrayInBitsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ArrayInBitsWriter =
+    GenericArrayInBitsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericArrayInBitsView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericArrayInBitsView<
+    GenericArrayInBitsView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericArrayInBitsView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeArrayInBitsView( T &&emboss_reserved_local_arg) {
+  return GenericArrayInBitsView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericArrayInBitsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeArrayInBitsView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericArrayInBitsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericArrayInBitsView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedArrayInBitsView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericArrayInBitsView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+namespace ArrayInBitsInStruct {
+
+}  // namespace ArrayInBitsInStruct
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericArrayInBitsInStructView;
+
+template <class Storage>
+class GenericArrayInBitsInStructView final {
+ public:
+  GenericArrayInBitsInStructView() : backing_() {}
+  explicit GenericArrayInBitsInStructView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericArrayInBitsInStructView(
+      const GenericArrayInBitsInStructView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericArrayInBitsInStructView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericArrayInBitsInStructView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericArrayInBitsInStructView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericArrayInBitsInStructView<Storage> &operator=(
+      const GenericArrayInBitsInStructView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_array_in_bits().Known()) return false;
+    if (has_array_in_bits().ValueOrDefault() && !array_in_bits().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericArrayInBitsInStructView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_array_in_bits().Known()) return false;
+    if (!emboss_reserved_local_other.has_array_in_bits().Known()) return false;
+
+    if (emboss_reserved_local_other.has_array_in_bits().ValueOrDefault() &&
+        !has_array_in_bits().ValueOrDefault())
+      return false;
+    if (has_array_in_bits().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_array_in_bits().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_array_in_bits().ValueOrDefault() &&
+        has_array_in_bits().ValueOrDefault() &&
+        !array_in_bits().Equals(emboss_reserved_local_other.array_in_bits()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericArrayInBitsInStructView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_array_in_bits().ValueOr(false) &&
+        !has_array_in_bits().ValueOr(false))
+      return false;
+    if (has_array_in_bits().ValueOr(false) &&
+        !emboss_reserved_local_other.has_array_in_bits().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_array_in_bits().ValueOr(false) &&
+        has_array_in_bits().ValueOr(false) &&
+        !array_in_bits().UncheckedEquals(emboss_reserved_local_other.array_in_bits()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericArrayInBitsInStructView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericArrayInBitsInStructView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericArrayInBitsInStructView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "array_in_bits") {
+        if (!array_in_bits().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_array_in_bits().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          array_in_bits().IsAggregate() || array_in_bits().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("array_in_bits: ");
+        array_in_bits().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !array_in_bits().IsAggregate() && !array_in_bits().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# array_in_bits: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::test::GenericArrayInBitsView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 16>>
+
+ array_in_bits() const;
+  ::emboss::support::Maybe<bool> has_array_in_bits() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericArrayInBitsInStructView;
+};
+using ArrayInBitsInStructView =
+    GenericArrayInBitsInStructView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ArrayInBitsInStructWriter =
+    GenericArrayInBitsInStructView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericArrayInBitsInStructView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericArrayInBitsInStructView<
+    GenericArrayInBitsInStructView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericArrayInBitsInStructView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeArrayInBitsInStructView( T &&emboss_reserved_local_arg) {
+  return GenericArrayInBitsInStructView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericArrayInBitsInStructView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeArrayInBitsInStructView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericArrayInBitsInStructView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericArrayInBitsInStructView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedArrayInBitsInStructView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericArrayInBitsInStructView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+
+namespace StructOfBits {
+
+}  // namespace StructOfBits
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructOfBitsView;
+
+template <class Storage>
+class GenericStructOfBitsView final {
+ public:
+  GenericStructOfBitsView() : backing_() {}
+  explicit GenericStructOfBitsView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructOfBitsView(
+      const GenericStructOfBitsView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericStructOfBitsView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericStructOfBitsView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericStructOfBitsView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructOfBitsView<Storage> &operator=(
+      const GenericStructOfBitsView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_one_byte().Known()) return false;
+    if (has_one_byte().ValueOrDefault() && !one_byte().Ok()) return false;
+
+
+    if (!has_two_byte().Known()) return false;
+    if (has_two_byte().ValueOrDefault() && !two_byte().Ok()) return false;
+
+
+    if (!has_four_byte().Known()) return false;
+    if (has_four_byte().ValueOrDefault() && !four_byte().Ok()) return false;
+
+
+    if (!has_located_byte().Known()) return false;
+    if (has_located_byte().ValueOrDefault() && !located_byte().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericStructOfBitsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_one_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_one_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOrDefault() &&
+        !has_one_byte().ValueOrDefault())
+      return false;
+    if (has_one_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_one_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOrDefault() &&
+        has_one_byte().ValueOrDefault() &&
+        !one_byte().Equals(emboss_reserved_local_other.one_byte()))
+      return false;
+
+
+
+    if (!has_two_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_two_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOrDefault() &&
+        !has_two_byte().ValueOrDefault())
+      return false;
+    if (has_two_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_two_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOrDefault() &&
+        has_two_byte().ValueOrDefault() &&
+        !two_byte().Equals(emboss_reserved_local_other.two_byte()))
+      return false;
+
+
+
+    if (!has_four_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_four_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOrDefault() &&
+        !has_four_byte().ValueOrDefault())
+      return false;
+    if (has_four_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_four_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOrDefault() &&
+        has_four_byte().ValueOrDefault() &&
+        !four_byte().Equals(emboss_reserved_local_other.four_byte()))
+      return false;
+
+
+
+    if (!has_located_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_located_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_located_byte().ValueOrDefault() &&
+        !has_located_byte().ValueOrDefault())
+      return false;
+    if (has_located_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_located_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_located_byte().ValueOrDefault() &&
+        has_located_byte().ValueOrDefault() &&
+        !located_byte().Equals(emboss_reserved_local_other.located_byte()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericStructOfBitsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_one_byte().ValueOr(false) &&
+        !has_one_byte().ValueOr(false))
+      return false;
+    if (has_one_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_one_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOr(false) &&
+        has_one_byte().ValueOr(false) &&
+        !one_byte().UncheckedEquals(emboss_reserved_local_other.one_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOr(false) &&
+        !has_two_byte().ValueOr(false))
+      return false;
+    if (has_two_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_two_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOr(false) &&
+        has_two_byte().ValueOr(false) &&
+        !two_byte().UncheckedEquals(emboss_reserved_local_other.two_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOr(false) &&
+        !has_four_byte().ValueOr(false))
+      return false;
+    if (has_four_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_four_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOr(false) &&
+        has_four_byte().ValueOr(false) &&
+        !four_byte().UncheckedEquals(emboss_reserved_local_other.four_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_located_byte().ValueOr(false) &&
+        !has_located_byte().ValueOr(false))
+      return false;
+    if (has_located_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_located_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_located_byte().ValueOr(false) &&
+        has_located_byte().ValueOr(false) &&
+        !located_byte().UncheckedEquals(emboss_reserved_local_other.located_byte()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericStructOfBitsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericStructOfBitsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericStructOfBitsView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "one_byte") {
+        if (!one_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "two_byte") {
+        if (!two_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "four_byte") {
+        if (!four_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "located_byte") {
+        if (!located_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_one_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          one_byte().IsAggregate() || one_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("one_byte: ");
+        one_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !one_byte().IsAggregate() && !one_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# one_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_two_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          two_byte().IsAggregate() || two_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("two_byte: ");
+        two_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !two_byte().IsAggregate() && !two_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# two_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_four_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          four_byte().IsAggregate() || four_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("four_byte: ");
+        four_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !four_byte().IsAggregate() && !four_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# four_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_located_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          located_byte().IsAggregate() || located_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("located_byte: ");
+        located_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !located_byte().IsAggregate() && !located_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# located_byte: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::test::GenericOneByteView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ one_byte() const;
+  ::emboss::support::Maybe<bool> has_one_byte() const;
+
+ public:
+  typename ::emboss::test::FourByte::GenericTwoByteWithGapsView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+ two_byte() const;
+  ::emboss::support::Maybe<bool> has_two_byte() const;
+
+ public:
+  typename ::emboss::test::GenericFourByteView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 32>>
+
+ four_byte() const;
+  ::emboss::support::Maybe<bool> has_four_byte() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+ located_byte() const;
+  ::emboss::support::Maybe<bool> has_located_byte() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericStructOfBitsView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.one_byte().mid_nibble();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(7LL)), emboss_reserved_local_subexpr_4);
+
+      return emboss_reserved_local_subexpr_5;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericStructOfBitsView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericStructOfBitsView;
+};
+using StructOfBitsView =
+    GenericStructOfBitsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using StructOfBitsWriter =
+    GenericStructOfBitsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructOfBitsView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericStructOfBitsView<
+    GenericStructOfBitsView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericStructOfBitsView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeStructOfBitsView( T &&emboss_reserved_local_arg) {
+  return GenericStructOfBitsView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericStructOfBitsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeStructOfBitsView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericStructOfBitsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericStructOfBitsView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedStructOfBitsView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericStructOfBitsView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+namespace BitArray {
+
+}  // namespace BitArray
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericBitArrayView;
+
+template <class Storage>
+class GenericBitArrayView final {
+ public:
+  GenericBitArrayView() : backing_() {}
+  explicit GenericBitArrayView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericBitArrayView(
+      const GenericBitArrayView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericBitArrayView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericBitArrayView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericBitArrayView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericBitArrayView<Storage> &operator=(
+      const GenericBitArrayView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_one_byte().Known()) return false;
+    if (has_one_byte().ValueOrDefault() && !one_byte().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericBitArrayView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_one_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_one_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOrDefault() &&
+        !has_one_byte().ValueOrDefault())
+      return false;
+    if (has_one_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_one_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOrDefault() &&
+        has_one_byte().ValueOrDefault() &&
+        !one_byte().Equals(emboss_reserved_local_other.one_byte()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericBitArrayView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_one_byte().ValueOr(false) &&
+        !has_one_byte().ValueOr(false))
+      return false;
+    if (has_one_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_one_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOr(false) &&
+        has_one_byte().ValueOr(false) &&
+        !one_byte().UncheckedEquals(emboss_reserved_local_other.one_byte()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericBitArrayView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericBitArrayView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericBitArrayView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "one_byte") {
+        if (!one_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_one_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          one_byte().IsAggregate() || one_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("one_byte: ");
+        one_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !one_byte().IsAggregate() && !one_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# one_byte: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericOneByteView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 1,
+    8 >
+
+ one_byte() const;
+  ::emboss::support::Maybe<bool> has_one_byte() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericBitArrayView;
+};
+using BitArrayView =
+    GenericBitArrayView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using BitArrayWriter =
+    GenericBitArrayView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericBitArrayView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericBitArrayView<
+    GenericBitArrayView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericBitArrayView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeBitArrayView( T &&emboss_reserved_local_arg) {
+  return GenericBitArrayView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericBitArrayView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeBitArrayView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericBitArrayView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericBitArrayView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedBitArrayView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericBitArrayView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace OneByte {
+
+}  // namespace OneByte
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 7>>
+
+ GenericOneByteView<Storage>::high_bit()
+    const {
+
+  if ( has_high_bit().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(7LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 7>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   7>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 7>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericOneByteView<Storage>::has_high_bit() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 6>>
+
+ GenericOneByteView<Storage>::less_high_bit()
+    const {
+
+  if ( has_less_high_bit().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 6>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   6>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 6>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericOneByteView<Storage>::has_less_high_bit() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 2>>
+
+ GenericOneByteView<Storage>::mid_nibble()
+    const {
+
+  if ( has_mid_nibble().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 2>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 2>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericOneByteView<Storage>::has_mid_nibble() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 1>>
+
+ GenericOneByteView<Storage>::less_low_bit()
+    const {
+
+  if ( has_less_low_bit().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 1>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 1>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericOneByteView<Storage>::has_less_low_bit() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericOneByteView<Storage>::low_bit()
+    const {
+
+  if ( has_low_bit().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericOneByteView<Storage>::has_low_bit() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace OneByte {
+inline constexpr ::std::int32_t IntrinsicSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace OneByte
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOneByteView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
+  return OneByte::IntrinsicSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOneByteView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
+  return OneByte::IntrinsicSizeInBits();
+}
+
+namespace OneByte {
+inline constexpr ::std::int32_t MaxSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace OneByte
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOneByteView<Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
+  return OneByte::MaxSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOneByteView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
+  return OneByte::MaxSizeInBits();
+}
+
+namespace OneByte {
+inline constexpr ::std::int32_t MinSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace OneByte
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOneByteView<Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
+  return OneByte::MinSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOneByteView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
+  return OneByte::MinSizeInBits();
+}
+namespace FourByte {
+namespace TwoByteWithGaps {
+
+}  // namespace TwoByteWithGaps
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 15>>
+
+ GenericTwoByteWithGapsView<Storage>::high_bit()
+    const {
+
+  if ( has_high_bit().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(15LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 15>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   15>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 15>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericTwoByteWithGapsView<Storage>::has_high_bit() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 6>>
+
+ GenericTwoByteWithGapsView<Storage>::mid_nibble()
+    const {
+
+  if ( has_mid_nibble().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 6>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   6>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 6>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericTwoByteWithGapsView<Storage>::has_mid_nibble() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericTwoByteWithGapsView<Storage>::low_bit()
+    const {
+
+  if ( has_low_bit().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericTwoByteWithGapsView<Storage>::has_low_bit() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace TwoByteWithGaps {
+inline constexpr ::std::int32_t IntrinsicSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(16LL)).ValueOrDefault();
+}
+}  // namespace TwoByteWithGaps
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericTwoByteWithGapsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
+  return TwoByteWithGaps::IntrinsicSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericTwoByteWithGapsView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
+  return TwoByteWithGaps::IntrinsicSizeInBits();
+}
+
+namespace TwoByteWithGaps {
+inline constexpr ::std::int32_t MaxSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(16LL)).ValueOrDefault();
+}
+}  // namespace TwoByteWithGaps
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericTwoByteWithGapsView<Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
+  return TwoByteWithGaps::MaxSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericTwoByteWithGapsView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
+  return TwoByteWithGaps::MaxSizeInBits();
+}
+
+namespace TwoByteWithGaps {
+inline constexpr ::std::int32_t MinSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(16LL)).ValueOrDefault();
+}
+}  // namespace TwoByteWithGaps
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericTwoByteWithGapsView<Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
+  return TwoByteWithGaps::MinSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericTwoByteWithGapsView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
+  return TwoByteWithGaps::MinSizeInBits();
+}
+
+}  // namespace FourByte
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 28>>
+
+ GenericFourByteView<Storage>::high_nibble()
+    const {
+
+  if ( has_high_nibble().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(28LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 28>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   28>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 28>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericFourByteView<Storage>::has_high_nibble() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericOneByteView<typename Storage::template OffsetStorageType</**/0, 20>>
+
+ GenericFourByteView<Storage>::one_byte()
+    const {
+
+  if ( has_one_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(20LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericOneByteView<typename Storage::template OffsetStorageType</**/0, 20>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   20>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericOneByteView<typename Storage::template OffsetStorageType</**/0, 20>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericFourByteView<Storage>::has_one_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::FourByte::GenericTwoByteWithGapsView<typename Storage::template OffsetStorageType</**/0, 4>>
+
+ GenericFourByteView<Storage>::two_byte()
+    const {
+
+  if ( has_two_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(16LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::FourByte::GenericTwoByteWithGapsView<typename Storage::template OffsetStorageType</**/0, 4>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   4>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::FourByte::GenericTwoByteWithGapsView<typename Storage::template OffsetStorageType</**/0, 4>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericFourByteView<Storage>::has_two_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, FourByte::EmbossReservedValidatorForRawLowNibble>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericFourByteView<Storage>::raw_low_nibble()
+    const {
+
+  if ( has_raw_low_nibble().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, FourByte::EmbossReservedValidatorForRawLowNibble>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, FourByte::EmbossReservedValidatorForRawLowNibble>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericFourByteView<Storage>::has_raw_low_nibble() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericFourByteView<Storage>::EmbossReservedVirtualLowNibbleView
+GenericFourByteView<Storage>::low_nibble() const {
+  return
+      typename GenericFourByteView<Storage>::EmbossReservedVirtualLowNibbleView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericFourByteView<Storage>::has_low_nibble() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace FourByte {
+inline constexpr ::std::int32_t IntrinsicSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(32LL)).ValueOrDefault();
+}
+}  // namespace FourByte
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFourByteView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
+  return FourByte::IntrinsicSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFourByteView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
+  return FourByte::IntrinsicSizeInBits();
+}
+
+namespace FourByte {
+inline constexpr ::std::int32_t MaxSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(32LL)).ValueOrDefault();
+}
+}  // namespace FourByte
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFourByteView<Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
+  return FourByte::MaxSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFourByteView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
+  return FourByte::MaxSizeInBits();
+}
+
+namespace FourByte {
+inline constexpr ::std::int32_t MinSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(32LL)).ValueOrDefault();
+}
+}  // namespace FourByte
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFourByteView<Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
+  return FourByte::MinSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFourByteView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
+  return FourByte::MinSizeInBits();
+}
+namespace ArrayInBits {
+
+}  // namespace ArrayInBits
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 15>>
+
+ GenericArrayInBitsView<Storage>::lone_flag()
+    const {
+
+  if ( has_lone_flag().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(15LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 15>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   15>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 15>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericArrayInBitsView<Storage>::has_lone_flag() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/1, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 1,
+    1 >
+
+ GenericArrayInBitsView<Storage>::flags()
+    const {
+
+  if ( has_flags().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(12LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/1, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 1,
+    1 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/1, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 1,
+    1 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericArrayInBitsView<Storage>::has_flags() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace ArrayInBits {
+inline constexpr ::std::int32_t IntrinsicSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(16LL)).ValueOrDefault();
+}
+}  // namespace ArrayInBits
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericArrayInBitsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
+  return ArrayInBits::IntrinsicSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericArrayInBitsView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
+  return ArrayInBits::IntrinsicSizeInBits();
+}
+
+namespace ArrayInBits {
+inline constexpr ::std::int32_t MaxSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(16LL)).ValueOrDefault();
+}
+}  // namespace ArrayInBits
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericArrayInBitsView<Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
+  return ArrayInBits::MaxSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericArrayInBitsView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
+  return ArrayInBits::MaxSizeInBits();
+}
+
+namespace ArrayInBits {
+inline constexpr ::std::int32_t MinSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(16LL)).ValueOrDefault();
+}
+}  // namespace ArrayInBits
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericArrayInBitsView<Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
+  return ArrayInBits::MinSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericArrayInBitsView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
+  return ArrayInBits::MinSizeInBits();
+}
+namespace ArrayInBitsInStruct {
+
+}  // namespace ArrayInBitsInStruct
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericArrayInBitsView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 16>>
+
+ GenericArrayInBitsInStructView<Storage>::array_in_bits()
+    const {
+
+  if ( has_array_in_bits().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericArrayInBitsView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 16>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericArrayInBitsView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 16>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericArrayInBitsInStructView<Storage>::has_array_in_bits() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace ArrayInBitsInStruct {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace ArrayInBitsInStruct
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericArrayInBitsInStructView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return ArrayInBitsInStruct::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericArrayInBitsInStructView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return ArrayInBitsInStruct::IntrinsicSizeInBytes();
+}
+
+namespace ArrayInBitsInStruct {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace ArrayInBitsInStruct
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericArrayInBitsInStructView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return ArrayInBitsInStruct::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericArrayInBitsInStructView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return ArrayInBitsInStruct::MaxSizeInBytes();
+}
+
+namespace ArrayInBitsInStruct {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace ArrayInBitsInStruct
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericArrayInBitsInStructView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return ArrayInBitsInStruct::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericArrayInBitsInStructView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return ArrayInBitsInStruct::MinSizeInBytes();
+}
+namespace StructOfBits {
+
+}  // namespace StructOfBits
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericOneByteView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericStructOfBitsView<Storage>::one_byte()
+    const {
+
+  if ( has_one_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericOneByteView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericOneByteView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructOfBitsView<Storage>::has_one_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::FourByte::GenericTwoByteWithGapsView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+ GenericStructOfBitsView<Storage>::two_byte()
+    const {
+
+  if ( has_two_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::FourByte::GenericTwoByteWithGapsView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::FourByte::GenericTwoByteWithGapsView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructOfBitsView<Storage>::has_two_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericFourByteView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 32>>
+
+ GenericStructOfBitsView<Storage>::four_byte()
+    const {
+
+  if ( has_four_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericFourByteView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   3>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericFourByteView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructOfBitsView<Storage>::has_four_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+ GenericStructOfBitsView<Storage>::located_byte()
+    const {
+
+  if ( has_located_byte().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = one_byte().mid_nibble();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_2;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructOfBitsView<Storage>::has_located_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericStructOfBitsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericStructOfBitsView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericStructOfBitsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructOfBitsView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace StructOfBits {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(16LL)).ValueOrDefault();
+}
+}  // namespace StructOfBits
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructOfBitsView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return StructOfBits::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructOfBitsView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return StructOfBits::MaxSizeInBytes();
+}
+
+namespace StructOfBits {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(7LL)).ValueOrDefault();
+}
+}  // namespace StructOfBits
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructOfBitsView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return StructOfBits::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructOfBitsView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return StructOfBits::MinSizeInBytes();
+}
+namespace BitArray {
+
+}  // namespace BitArray
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericOneByteView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 1,
+    8 >
+
+ GenericBitArrayView<Storage>::one_byte()
+    const {
+
+  if ( has_one_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericOneByteView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 1,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericOneByteView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 1,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBitArrayView<Storage>::has_one_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace BitArray {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace BitArray
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBitArrayView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return BitArray::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBitArrayView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return BitArray::IntrinsicSizeInBytes();
+}
+
+namespace BitArray {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace BitArray
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBitArrayView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return BitArray::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBitArrayView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return BitArray::MaxSizeInBytes();
+}
+
+namespace BitArray {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace BitArray
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBitArrayView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return BitArray::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBitArrayView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return BitArray::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_BITS_EMB_H_
+
diff --git a/testdata/golden_cpp/complex_offset.emb.h b/testdata/golden_cpp/complex_offset.emb.h
new file mode 100644
index 0000000..31889b0
--- /dev/null
+++ b/testdata/golden_cpp/complex_offset.emb.h
@@ -0,0 +1,3689 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_COMPLEX_OFFSET_EMB_H_
+#define TESTDATA_COMPLEX_OFFSET_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace Length {
+
+}  // namespace Length
+
+
+template <class Storage>
+class GenericLengthView;
+
+namespace Data {
+
+}  // namespace Data
+
+
+template <class Storage>
+class GenericDataView;
+
+namespace PackedFields {
+
+}  // namespace PackedFields
+
+
+template <class Storage>
+class GenericPackedFieldsView;
+
+
+
+
+
+namespace Length {
+
+}  // namespace Length
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericLengthView;
+
+template <class Storage>
+class GenericLengthView final {
+ public:
+  GenericLengthView() : backing_() {}
+  explicit GenericLengthView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericLengthView(
+      const GenericLengthView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericLengthView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericLengthView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericLengthView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericLengthView<Storage> &operator=(
+      const GenericLengthView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_length().Known()) return false;
+    if (has_length().ValueOrDefault() && !length().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericLengthView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_length().Known()) return false;
+    if (!emboss_reserved_local_other.has_length().Known()) return false;
+
+    if (emboss_reserved_local_other.has_length().ValueOrDefault() &&
+        !has_length().ValueOrDefault())
+      return false;
+    if (has_length().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_length().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_length().ValueOrDefault() &&
+        has_length().ValueOrDefault() &&
+        !length().Equals(emboss_reserved_local_other.length()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericLengthView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_length().ValueOr(false) &&
+        !has_length().ValueOr(false))
+      return false;
+    if (has_length().ValueOr(false) &&
+        !emboss_reserved_local_other.has_length().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_length().ValueOr(false) &&
+        has_length().ValueOr(false) &&
+        !length().UncheckedEquals(emboss_reserved_local_other.length()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericLengthView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericLengthView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericLengthView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "length") {
+        if (!length().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_length().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          length().IsAggregate() || length().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("length: ");
+        length().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !length().IsAggregate() && !length().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# length: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ length() const;
+  ::emboss::support::Maybe<bool> has_length() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericLengthView;
+};
+using LengthView =
+    GenericLengthView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using LengthWriter =
+    GenericLengthView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericLengthView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericLengthView<
+    GenericLengthView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericLengthView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeLengthView( T &&emboss_reserved_local_arg) {
+  return GenericLengthView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericLengthView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeLengthView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericLengthView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericLengthView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedLengthView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericLengthView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace Data {
+
+}  // namespace Data
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericDataView;
+
+template <class Storage>
+class GenericDataView final {
+ public:
+  GenericDataView() : backing_() {}
+  explicit GenericDataView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericDataView(
+      const GenericDataView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericDataView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericDataView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericDataView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericDataView<Storage> &operator=(
+      const GenericDataView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_length().Known()) return false;
+    if (has_length().ValueOrDefault() && !length().Ok()) return false;
+
+
+    if (!has_data().Known()) return false;
+    if (has_data().ValueOrDefault() && !data().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericDataView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_length().Known()) return false;
+    if (!emboss_reserved_local_other.has_length().Known()) return false;
+
+    if (emboss_reserved_local_other.has_length().ValueOrDefault() &&
+        !has_length().ValueOrDefault())
+      return false;
+    if (has_length().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_length().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_length().ValueOrDefault() &&
+        has_length().ValueOrDefault() &&
+        !length().Equals(emboss_reserved_local_other.length()))
+      return false;
+
+
+
+    if (!has_data().Known()) return false;
+    if (!emboss_reserved_local_other.has_data().Known()) return false;
+
+    if (emboss_reserved_local_other.has_data().ValueOrDefault() &&
+        !has_data().ValueOrDefault())
+      return false;
+    if (has_data().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_data().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_data().ValueOrDefault() &&
+        has_data().ValueOrDefault() &&
+        !data().Equals(emboss_reserved_local_other.data()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericDataView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_length().ValueOr(false) &&
+        !has_length().ValueOr(false))
+      return false;
+    if (has_length().ValueOr(false) &&
+        !emboss_reserved_local_other.has_length().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_length().ValueOr(false) &&
+        has_length().ValueOr(false) &&
+        !length().UncheckedEquals(emboss_reserved_local_other.length()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_data().ValueOr(false) &&
+        !has_data().ValueOr(false))
+      return false;
+    if (has_data().ValueOr(false) &&
+        !emboss_reserved_local_other.has_data().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_data().ValueOr(false) &&
+        has_data().ValueOr(false) &&
+        !data().UncheckedEquals(emboss_reserved_local_other.data()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericDataView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericDataView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericDataView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "length") {
+        if (!length().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "data") {
+        if (!data().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_length().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          length().IsAggregate() || length().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("length: ");
+        length().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !length().IsAggregate() && !length().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# length: UNREADABLE\n");
+      }
+    }
+
+    if (has_data().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          data().IsAggregate() || data().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("data: ");
+        data().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !data().IsAggregate() && !data().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# data: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ length() const;
+  ::emboss::support::Maybe<bool> has_length() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 1>, 1,
+    8 >
+
+ data() const;
+  ::emboss::support::Maybe<bool> has_data() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericDataView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.length().length();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_2);
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_4);
+
+      return emboss_reserved_local_subexpr_5;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericDataView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericDataView;
+};
+using DataView =
+    GenericDataView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using DataWriter =
+    GenericDataView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericDataView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericDataView<
+    GenericDataView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericDataView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeDataView( T &&emboss_reserved_local_arg) {
+  return GenericDataView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericDataView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeDataView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericDataView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericDataView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedDataView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericDataView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+namespace PackedFields {
+
+}  // namespace PackedFields
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericPackedFieldsView;
+
+template <class Storage>
+class GenericPackedFieldsView final {
+ public:
+  GenericPackedFieldsView() : backing_() {}
+  explicit GenericPackedFieldsView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericPackedFieldsView(
+      const GenericPackedFieldsView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericPackedFieldsView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericPackedFieldsView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericPackedFieldsView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericPackedFieldsView<Storage> &operator=(
+      const GenericPackedFieldsView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_length1().Known()) return false;
+    if (has_length1().ValueOrDefault() && !length1().Ok()) return false;
+
+
+    if (!has_data1().Known()) return false;
+    if (has_data1().ValueOrDefault() && !data1().Ok()) return false;
+
+
+    if (!has_o1().Known()) return false;
+    if (has_o1().ValueOrDefault() && !o1().Ok()) return false;
+
+
+    if (!has_length2().Known()) return false;
+    if (has_length2().ValueOrDefault() && !length2().Ok()) return false;
+
+
+    if (!has_data2().Known()) return false;
+    if (has_data2().ValueOrDefault() && !data2().Ok()) return false;
+
+
+    if (!has_o2().Known()) return false;
+    if (has_o2().ValueOrDefault() && !o2().Ok()) return false;
+
+
+    if (!has_length3().Known()) return false;
+    if (has_length3().ValueOrDefault() && !length3().Ok()) return false;
+
+
+    if (!has_data3().Known()) return false;
+    if (has_data3().ValueOrDefault() && !data3().Ok()) return false;
+
+
+    if (!has_o3().Known()) return false;
+    if (has_o3().ValueOrDefault() && !o3().Ok()) return false;
+
+
+    if (!has_length4().Known()) return false;
+    if (has_length4().ValueOrDefault() && !length4().Ok()) return false;
+
+
+    if (!has_data4().Known()) return false;
+    if (has_data4().ValueOrDefault() && !data4().Ok()) return false;
+
+
+    if (!has_o4().Known()) return false;
+    if (has_o4().ValueOrDefault() && !o4().Ok()) return false;
+
+
+    if (!has_length5().Known()) return false;
+    if (has_length5().ValueOrDefault() && !length5().Ok()) return false;
+
+
+    if (!has_data5().Known()) return false;
+    if (has_data5().ValueOrDefault() && !data5().Ok()) return false;
+
+
+    if (!has_o5().Known()) return false;
+    if (has_o5().ValueOrDefault() && !o5().Ok()) return false;
+
+
+    if (!has_length6().Known()) return false;
+    if (has_length6().ValueOrDefault() && !length6().Ok()) return false;
+
+
+    if (!has_data6().Known()) return false;
+    if (has_data6().ValueOrDefault() && !data6().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericPackedFieldsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_length1().Known()) return false;
+    if (!emboss_reserved_local_other.has_length1().Known()) return false;
+
+    if (emboss_reserved_local_other.has_length1().ValueOrDefault() &&
+        !has_length1().ValueOrDefault())
+      return false;
+    if (has_length1().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_length1().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_length1().ValueOrDefault() &&
+        has_length1().ValueOrDefault() &&
+        !length1().Equals(emboss_reserved_local_other.length1()))
+      return false;
+
+
+
+    if (!has_data1().Known()) return false;
+    if (!emboss_reserved_local_other.has_data1().Known()) return false;
+
+    if (emboss_reserved_local_other.has_data1().ValueOrDefault() &&
+        !has_data1().ValueOrDefault())
+      return false;
+    if (has_data1().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_data1().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_data1().ValueOrDefault() &&
+        has_data1().ValueOrDefault() &&
+        !data1().Equals(emboss_reserved_local_other.data1()))
+      return false;
+
+
+
+    if (!has_length2().Known()) return false;
+    if (!emboss_reserved_local_other.has_length2().Known()) return false;
+
+    if (emboss_reserved_local_other.has_length2().ValueOrDefault() &&
+        !has_length2().ValueOrDefault())
+      return false;
+    if (has_length2().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_length2().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_length2().ValueOrDefault() &&
+        has_length2().ValueOrDefault() &&
+        !length2().Equals(emboss_reserved_local_other.length2()))
+      return false;
+
+
+
+    if (!has_data2().Known()) return false;
+    if (!emboss_reserved_local_other.has_data2().Known()) return false;
+
+    if (emboss_reserved_local_other.has_data2().ValueOrDefault() &&
+        !has_data2().ValueOrDefault())
+      return false;
+    if (has_data2().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_data2().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_data2().ValueOrDefault() &&
+        has_data2().ValueOrDefault() &&
+        !data2().Equals(emboss_reserved_local_other.data2()))
+      return false;
+
+
+
+    if (!has_length3().Known()) return false;
+    if (!emboss_reserved_local_other.has_length3().Known()) return false;
+
+    if (emboss_reserved_local_other.has_length3().ValueOrDefault() &&
+        !has_length3().ValueOrDefault())
+      return false;
+    if (has_length3().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_length3().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_length3().ValueOrDefault() &&
+        has_length3().ValueOrDefault() &&
+        !length3().Equals(emboss_reserved_local_other.length3()))
+      return false;
+
+
+
+    if (!has_data3().Known()) return false;
+    if (!emboss_reserved_local_other.has_data3().Known()) return false;
+
+    if (emboss_reserved_local_other.has_data3().ValueOrDefault() &&
+        !has_data3().ValueOrDefault())
+      return false;
+    if (has_data3().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_data3().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_data3().ValueOrDefault() &&
+        has_data3().ValueOrDefault() &&
+        !data3().Equals(emboss_reserved_local_other.data3()))
+      return false;
+
+
+
+    if (!has_length4().Known()) return false;
+    if (!emboss_reserved_local_other.has_length4().Known()) return false;
+
+    if (emboss_reserved_local_other.has_length4().ValueOrDefault() &&
+        !has_length4().ValueOrDefault())
+      return false;
+    if (has_length4().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_length4().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_length4().ValueOrDefault() &&
+        has_length4().ValueOrDefault() &&
+        !length4().Equals(emboss_reserved_local_other.length4()))
+      return false;
+
+
+
+    if (!has_data4().Known()) return false;
+    if (!emboss_reserved_local_other.has_data4().Known()) return false;
+
+    if (emboss_reserved_local_other.has_data4().ValueOrDefault() &&
+        !has_data4().ValueOrDefault())
+      return false;
+    if (has_data4().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_data4().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_data4().ValueOrDefault() &&
+        has_data4().ValueOrDefault() &&
+        !data4().Equals(emboss_reserved_local_other.data4()))
+      return false;
+
+
+
+    if (!has_length5().Known()) return false;
+    if (!emboss_reserved_local_other.has_length5().Known()) return false;
+
+    if (emboss_reserved_local_other.has_length5().ValueOrDefault() &&
+        !has_length5().ValueOrDefault())
+      return false;
+    if (has_length5().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_length5().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_length5().ValueOrDefault() &&
+        has_length5().ValueOrDefault() &&
+        !length5().Equals(emboss_reserved_local_other.length5()))
+      return false;
+
+
+
+    if (!has_data5().Known()) return false;
+    if (!emboss_reserved_local_other.has_data5().Known()) return false;
+
+    if (emboss_reserved_local_other.has_data5().ValueOrDefault() &&
+        !has_data5().ValueOrDefault())
+      return false;
+    if (has_data5().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_data5().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_data5().ValueOrDefault() &&
+        has_data5().ValueOrDefault() &&
+        !data5().Equals(emboss_reserved_local_other.data5()))
+      return false;
+
+
+
+    if (!has_length6().Known()) return false;
+    if (!emboss_reserved_local_other.has_length6().Known()) return false;
+
+    if (emboss_reserved_local_other.has_length6().ValueOrDefault() &&
+        !has_length6().ValueOrDefault())
+      return false;
+    if (has_length6().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_length6().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_length6().ValueOrDefault() &&
+        has_length6().ValueOrDefault() &&
+        !length6().Equals(emboss_reserved_local_other.length6()))
+      return false;
+
+
+
+    if (!has_data6().Known()) return false;
+    if (!emboss_reserved_local_other.has_data6().Known()) return false;
+
+    if (emboss_reserved_local_other.has_data6().ValueOrDefault() &&
+        !has_data6().ValueOrDefault())
+      return false;
+    if (has_data6().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_data6().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_data6().ValueOrDefault() &&
+        has_data6().ValueOrDefault() &&
+        !data6().Equals(emboss_reserved_local_other.data6()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericPackedFieldsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_length1().ValueOr(false) &&
+        !has_length1().ValueOr(false))
+      return false;
+    if (has_length1().ValueOr(false) &&
+        !emboss_reserved_local_other.has_length1().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_length1().ValueOr(false) &&
+        has_length1().ValueOr(false) &&
+        !length1().UncheckedEquals(emboss_reserved_local_other.length1()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_data1().ValueOr(false) &&
+        !has_data1().ValueOr(false))
+      return false;
+    if (has_data1().ValueOr(false) &&
+        !emboss_reserved_local_other.has_data1().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_data1().ValueOr(false) &&
+        has_data1().ValueOr(false) &&
+        !data1().UncheckedEquals(emboss_reserved_local_other.data1()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_length2().ValueOr(false) &&
+        !has_length2().ValueOr(false))
+      return false;
+    if (has_length2().ValueOr(false) &&
+        !emboss_reserved_local_other.has_length2().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_length2().ValueOr(false) &&
+        has_length2().ValueOr(false) &&
+        !length2().UncheckedEquals(emboss_reserved_local_other.length2()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_data2().ValueOr(false) &&
+        !has_data2().ValueOr(false))
+      return false;
+    if (has_data2().ValueOr(false) &&
+        !emboss_reserved_local_other.has_data2().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_data2().ValueOr(false) &&
+        has_data2().ValueOr(false) &&
+        !data2().UncheckedEquals(emboss_reserved_local_other.data2()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_length3().ValueOr(false) &&
+        !has_length3().ValueOr(false))
+      return false;
+    if (has_length3().ValueOr(false) &&
+        !emboss_reserved_local_other.has_length3().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_length3().ValueOr(false) &&
+        has_length3().ValueOr(false) &&
+        !length3().UncheckedEquals(emboss_reserved_local_other.length3()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_data3().ValueOr(false) &&
+        !has_data3().ValueOr(false))
+      return false;
+    if (has_data3().ValueOr(false) &&
+        !emboss_reserved_local_other.has_data3().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_data3().ValueOr(false) &&
+        has_data3().ValueOr(false) &&
+        !data3().UncheckedEquals(emboss_reserved_local_other.data3()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_length4().ValueOr(false) &&
+        !has_length4().ValueOr(false))
+      return false;
+    if (has_length4().ValueOr(false) &&
+        !emboss_reserved_local_other.has_length4().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_length4().ValueOr(false) &&
+        has_length4().ValueOr(false) &&
+        !length4().UncheckedEquals(emboss_reserved_local_other.length4()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_data4().ValueOr(false) &&
+        !has_data4().ValueOr(false))
+      return false;
+    if (has_data4().ValueOr(false) &&
+        !emboss_reserved_local_other.has_data4().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_data4().ValueOr(false) &&
+        has_data4().ValueOr(false) &&
+        !data4().UncheckedEquals(emboss_reserved_local_other.data4()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_length5().ValueOr(false) &&
+        !has_length5().ValueOr(false))
+      return false;
+    if (has_length5().ValueOr(false) &&
+        !emboss_reserved_local_other.has_length5().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_length5().ValueOr(false) &&
+        has_length5().ValueOr(false) &&
+        !length5().UncheckedEquals(emboss_reserved_local_other.length5()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_data5().ValueOr(false) &&
+        !has_data5().ValueOr(false))
+      return false;
+    if (has_data5().ValueOr(false) &&
+        !emboss_reserved_local_other.has_data5().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_data5().ValueOr(false) &&
+        has_data5().ValueOr(false) &&
+        !data5().UncheckedEquals(emboss_reserved_local_other.data5()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_length6().ValueOr(false) &&
+        !has_length6().ValueOr(false))
+      return false;
+    if (has_length6().ValueOr(false) &&
+        !emboss_reserved_local_other.has_length6().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_length6().ValueOr(false) &&
+        has_length6().ValueOr(false) &&
+        !length6().UncheckedEquals(emboss_reserved_local_other.length6()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_data6().ValueOr(false) &&
+        !has_data6().ValueOr(false))
+      return false;
+    if (has_data6().ValueOr(false) &&
+        !emboss_reserved_local_other.has_data6().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_data6().ValueOr(false) &&
+        has_data6().ValueOr(false) &&
+        !data6().UncheckedEquals(emboss_reserved_local_other.data6()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericPackedFieldsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericPackedFieldsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericPackedFieldsView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "length1") {
+        if (!length1().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "data1") {
+        if (!data1().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "length2") {
+        if (!length2().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "data2") {
+        if (!data2().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "length3") {
+        if (!length3().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "data3") {
+        if (!data3().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "length4") {
+        if (!length4().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "data4") {
+        if (!data4().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "length5") {
+        if (!length5().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "data5") {
+        if (!data5().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "length6") {
+        if (!length6().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "data6") {
+        if (!data6().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_length1().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          length1().IsAggregate() || length1().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("length1: ");
+        length1().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !length1().IsAggregate() && !length1().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# length1: UNREADABLE\n");
+      }
+    }
+
+    if (has_data1().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          data1().IsAggregate() || data1().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("data1: ");
+        data1().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !data1().IsAggregate() && !data1().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# data1: UNREADABLE\n");
+      }
+    }
+
+    if (has_o1().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          o1().IsAggregate() || o1().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# o1: ");
+        o1().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# o1: UNREADABLE\n");
+      }
+    }
+
+    if (has_length2().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          length2().IsAggregate() || length2().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("length2: ");
+        length2().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !length2().IsAggregate() && !length2().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# length2: UNREADABLE\n");
+      }
+    }
+
+    if (has_data2().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          data2().IsAggregate() || data2().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("data2: ");
+        data2().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !data2().IsAggregate() && !data2().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# data2: UNREADABLE\n");
+      }
+    }
+
+    if (has_o2().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          o2().IsAggregate() || o2().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# o2: ");
+        o2().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# o2: UNREADABLE\n");
+      }
+    }
+
+    if (has_length3().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          length3().IsAggregate() || length3().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("length3: ");
+        length3().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !length3().IsAggregate() && !length3().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# length3: UNREADABLE\n");
+      }
+    }
+
+    if (has_data3().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          data3().IsAggregate() || data3().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("data3: ");
+        data3().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !data3().IsAggregate() && !data3().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# data3: UNREADABLE\n");
+      }
+    }
+
+    if (has_o3().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          o3().IsAggregate() || o3().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# o3: ");
+        o3().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# o3: UNREADABLE\n");
+      }
+    }
+
+    if (has_length4().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          length4().IsAggregate() || length4().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("length4: ");
+        length4().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !length4().IsAggregate() && !length4().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# length4: UNREADABLE\n");
+      }
+    }
+
+    if (has_data4().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          data4().IsAggregate() || data4().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("data4: ");
+        data4().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !data4().IsAggregate() && !data4().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# data4: UNREADABLE\n");
+      }
+    }
+
+    if (has_o4().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          o4().IsAggregate() || o4().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# o4: ");
+        o4().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# o4: UNREADABLE\n");
+      }
+    }
+
+    if (has_length5().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          length5().IsAggregate() || length5().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("length5: ");
+        length5().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !length5().IsAggregate() && !length5().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# length5: UNREADABLE\n");
+      }
+    }
+
+    if (has_data5().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          data5().IsAggregate() || data5().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("data5: ");
+        data5().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !data5().IsAggregate() && !data5().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# data5: UNREADABLE\n");
+      }
+    }
+
+    if (has_o5().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          o5().IsAggregate() || o5().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# o5: ");
+        o5().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# o5: UNREADABLE\n");
+      }
+    }
+
+    if (has_length6().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          length6().IsAggregate() || length6().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("length6: ");
+        length6().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !length6().IsAggregate() && !length6().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# length6: UNREADABLE\n");
+      }
+    }
+
+    if (has_data6().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          data6().IsAggregate() || data6().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("data6: ");
+        data6().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !data6().IsAggregate() && !data6().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# data6: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ length1() const;
+  ::emboss::support::Maybe<bool> has_length1() const;
+
+ public:
+  typename ::emboss::test::GenericDataView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ data1() const;
+  ::emboss::support::Maybe<bool> has_data1() const;
+
+ public:
+  class EmbossReservedVirtualO1View final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedVirtualO1View(
+        const GenericPackedFieldsView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualO1View() = delete;
+    EmbossReservedVirtualO1View(const EmbossReservedVirtualO1View &) = default;
+    EmbossReservedVirtualO1View(EmbossReservedVirtualO1View &&) = default;
+    EmbossReservedVirtualO1View &operator=(const EmbossReservedVirtualO1View &) =
+        default;
+    EmbossReservedVirtualO1View &operator=(EmbossReservedVirtualO1View &&) =
+        default;
+    ~EmbossReservedVirtualO1View() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_o1().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.data1().IntrinsicSizeInBytes();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+
+      return emboss_reserved_local_subexpr_2;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericPackedFieldsView view_;
+  };
+  EmbossReservedVirtualO1View o1() const;
+  ::emboss::support::Maybe<bool> has_o1() const;
+
+ public:
+  typename ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+ length2() const;
+  ::emboss::support::Maybe<bool> has_length2() const;
+
+ public:
+  typename ::emboss::test::GenericDataView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+ data2() const;
+  ::emboss::support::Maybe<bool> has_data2() const;
+
+ public:
+  class EmbossReservedVirtualO2View final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedVirtualO2View(
+        const GenericPackedFieldsView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualO2View() = delete;
+    EmbossReservedVirtualO2View(const EmbossReservedVirtualO2View &) = default;
+    EmbossReservedVirtualO2View(EmbossReservedVirtualO2View &&) = default;
+    EmbossReservedVirtualO2View &operator=(const EmbossReservedVirtualO2View &) =
+        default;
+    EmbossReservedVirtualO2View &operator=(EmbossReservedVirtualO2View &&) =
+        default;
+    ~EmbossReservedVirtualO2View() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_o2().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.o1();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = view_.data2().IntrinsicSizeInBytes();
+      const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_4);
+
+      return emboss_reserved_local_subexpr_5;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericPackedFieldsView view_;
+  };
+  EmbossReservedVirtualO2View o2() const;
+  ::emboss::support::Maybe<bool> has_o2() const;
+
+ public:
+  typename ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+ length3() const;
+  ::emboss::support::Maybe<bool> has_length3() const;
+
+ public:
+  typename ::emboss::test::GenericDataView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+ data3() const;
+  ::emboss::support::Maybe<bool> has_data3() const;
+
+ public:
+  class EmbossReservedVirtualO3View final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedVirtualO3View(
+        const GenericPackedFieldsView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualO3View() = delete;
+    EmbossReservedVirtualO3View(const EmbossReservedVirtualO3View &) = default;
+    EmbossReservedVirtualO3View(EmbossReservedVirtualO3View &&) = default;
+    EmbossReservedVirtualO3View &operator=(const EmbossReservedVirtualO3View &) =
+        default;
+    EmbossReservedVirtualO3View &operator=(EmbossReservedVirtualO3View &&) =
+        default;
+    ~EmbossReservedVirtualO3View() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_o3().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.o2();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = view_.data3().IntrinsicSizeInBytes();
+      const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_4);
+
+      return emboss_reserved_local_subexpr_5;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericPackedFieldsView view_;
+  };
+  EmbossReservedVirtualO3View o3() const;
+  ::emboss::support::Maybe<bool> has_o3() const;
+
+ public:
+  typename ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+ length4() const;
+  ::emboss::support::Maybe<bool> has_length4() const;
+
+ public:
+  typename ::emboss::test::GenericDataView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+ data4() const;
+  ::emboss::support::Maybe<bool> has_data4() const;
+
+ public:
+  class EmbossReservedVirtualO4View final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedVirtualO4View(
+        const GenericPackedFieldsView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualO4View() = delete;
+    EmbossReservedVirtualO4View(const EmbossReservedVirtualO4View &) = default;
+    EmbossReservedVirtualO4View(EmbossReservedVirtualO4View &&) = default;
+    EmbossReservedVirtualO4View &operator=(const EmbossReservedVirtualO4View &) =
+        default;
+    EmbossReservedVirtualO4View &operator=(EmbossReservedVirtualO4View &&) =
+        default;
+    ~EmbossReservedVirtualO4View() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_o4().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.o3();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = view_.data4().IntrinsicSizeInBytes();
+      const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_4);
+
+      return emboss_reserved_local_subexpr_5;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericPackedFieldsView view_;
+  };
+  EmbossReservedVirtualO4View o4() const;
+  ::emboss::support::Maybe<bool> has_o4() const;
+
+ public:
+  typename ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+ length5() const;
+  ::emboss::support::Maybe<bool> has_length5() const;
+
+ public:
+  typename ::emboss::test::GenericDataView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+ data5() const;
+  ::emboss::support::Maybe<bool> has_data5() const;
+
+ public:
+  class EmbossReservedVirtualO5View final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedVirtualO5View(
+        const GenericPackedFieldsView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualO5View() = delete;
+    EmbossReservedVirtualO5View(const EmbossReservedVirtualO5View &) = default;
+    EmbossReservedVirtualO5View(EmbossReservedVirtualO5View &&) = default;
+    EmbossReservedVirtualO5View &operator=(const EmbossReservedVirtualO5View &) =
+        default;
+    EmbossReservedVirtualO5View &operator=(EmbossReservedVirtualO5View &&) =
+        default;
+    ~EmbossReservedVirtualO5View() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_o5().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.o4();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = view_.data5().IntrinsicSizeInBytes();
+      const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_4);
+
+      return emboss_reserved_local_subexpr_5;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericPackedFieldsView view_;
+  };
+  EmbossReservedVirtualO5View o5() const;
+  ::emboss::support::Maybe<bool> has_o5() const;
+
+ public:
+  typename ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+ length6() const;
+  ::emboss::support::Maybe<bool> has_length6() const;
+
+ public:
+  typename ::emboss::test::GenericDataView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+ data6() const;
+  ::emboss::support::Maybe<bool> has_data6() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericPackedFieldsView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.length1().length();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), emboss_reserved_local_subexpr_3);
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_4, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_6 = view_.o1();
+      const auto emboss_reserved_local_subexpr_7 = (emboss_reserved_local_subexpr_6.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_6.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_8 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_7, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      const auto emboss_reserved_local_subexpr_9 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_8, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_10 = view_.length2().length();
+      const auto emboss_reserved_local_subexpr_11 = (emboss_reserved_local_subexpr_10.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_10.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_12 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_11, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      const auto emboss_reserved_local_subexpr_13 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_7, emboss_reserved_local_subexpr_12);
+      const auto emboss_reserved_local_subexpr_14 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_13, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_15 = view_.o2();
+      const auto emboss_reserved_local_subexpr_16 = (emboss_reserved_local_subexpr_15.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_15.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_17 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_16, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      const auto emboss_reserved_local_subexpr_18 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_17, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_19 = view_.length3().length();
+      const auto emboss_reserved_local_subexpr_20 = (emboss_reserved_local_subexpr_19.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_19.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_21 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_20, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      const auto emboss_reserved_local_subexpr_22 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_16, emboss_reserved_local_subexpr_21);
+      const auto emboss_reserved_local_subexpr_23 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_22, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_24 = view_.o3();
+      const auto emboss_reserved_local_subexpr_25 = (emboss_reserved_local_subexpr_24.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_24.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_26 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_25, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      const auto emboss_reserved_local_subexpr_27 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_26, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_28 = view_.length4().length();
+      const auto emboss_reserved_local_subexpr_29 = (emboss_reserved_local_subexpr_28.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_28.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_30 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_29, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      const auto emboss_reserved_local_subexpr_31 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_25, emboss_reserved_local_subexpr_30);
+      const auto emboss_reserved_local_subexpr_32 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_31, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_33 = view_.o4();
+      const auto emboss_reserved_local_subexpr_34 = (emboss_reserved_local_subexpr_33.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_33.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_35 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_34, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      const auto emboss_reserved_local_subexpr_36 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_35, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_37 = view_.length5().length();
+      const auto emboss_reserved_local_subexpr_38 = (emboss_reserved_local_subexpr_37.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_37.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_39 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_38, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      const auto emboss_reserved_local_subexpr_40 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_34, emboss_reserved_local_subexpr_39);
+      const auto emboss_reserved_local_subexpr_41 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_40, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_42 = view_.o5();
+      const auto emboss_reserved_local_subexpr_43 = (emboss_reserved_local_subexpr_42.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_42.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_44 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_43, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      const auto emboss_reserved_local_subexpr_45 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_44, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_46 = view_.length6().length();
+      const auto emboss_reserved_local_subexpr_47 = (emboss_reserved_local_subexpr_46.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_46.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_48 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_47, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      const auto emboss_reserved_local_subexpr_49 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_43, emboss_reserved_local_subexpr_48);
+      const auto emboss_reserved_local_subexpr_50 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_49, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_51 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_5, emboss_reserved_local_subexpr_9, emboss_reserved_local_subexpr_14, emboss_reserved_local_subexpr_18, emboss_reserved_local_subexpr_23, emboss_reserved_local_subexpr_27, emboss_reserved_local_subexpr_32, emboss_reserved_local_subexpr_36, emboss_reserved_local_subexpr_41, emboss_reserved_local_subexpr_45, emboss_reserved_local_subexpr_50);
+
+      return emboss_reserved_local_subexpr_51;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericPackedFieldsView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericPackedFieldsView;
+};
+using PackedFieldsView =
+    GenericPackedFieldsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using PackedFieldsWriter =
+    GenericPackedFieldsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericPackedFieldsView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericPackedFieldsView<
+    GenericPackedFieldsView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericPackedFieldsView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakePackedFieldsView( T &&emboss_reserved_local_arg) {
+  return GenericPackedFieldsView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericPackedFieldsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakePackedFieldsView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericPackedFieldsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericPackedFieldsView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedPackedFieldsView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericPackedFieldsView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace Length {
+
+}  // namespace Length
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericLengthView<Storage>::length()
+    const {
+
+  if ( has_length().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericLengthView<Storage>::has_length() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Length {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace Length
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericLengthView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Length::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericLengthView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Length::IntrinsicSizeInBytes();
+}
+
+namespace Length {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace Length
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericLengthView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Length::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericLengthView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Length::MaxSizeInBytes();
+}
+
+namespace Length {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace Length
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericLengthView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Length::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericLengthView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Length::MinSizeInBytes();
+}
+namespace Data {
+
+}  // namespace Data
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericDataView<Storage>::length()
+    const {
+
+  if ( has_length().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericDataView<Storage>::has_length() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 1>, 1,
+    8 >
+
+ GenericDataView<Storage>::data()
+    const {
+
+  if ( has_data().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = length().length();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_2;
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 1>, 1,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 1>, 1,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericDataView<Storage>::has_data() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericDataView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericDataView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericDataView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericDataView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Data {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(256LL)).ValueOrDefault();
+}
+}  // namespace Data
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericDataView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Data::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericDataView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Data::MaxSizeInBytes();
+}
+
+namespace Data {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace Data
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericDataView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Data::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericDataView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Data::MinSizeInBytes();
+}
+namespace PackedFields {
+
+}  // namespace PackedFields
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericPackedFieldsView<Storage>::length1()
+    const {
+
+  if ( has_length1().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericPackedFieldsView<Storage>::has_length1() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericDataView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericPackedFieldsView<Storage>::data1()
+    const {
+
+  if ( has_data1().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = length1().length();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_3;
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericDataView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericDataView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericPackedFieldsView<Storage>::has_data1() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericPackedFieldsView<Storage>::EmbossReservedVirtualO1View
+GenericPackedFieldsView<Storage>::o1() const {
+  return
+      typename GenericPackedFieldsView<Storage>::EmbossReservedVirtualO1View(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericPackedFieldsView<Storage>::has_o1() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+ GenericPackedFieldsView<Storage>::length2()
+    const {
+
+  if ( has_length2().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = o1();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_2;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericPackedFieldsView<Storage>::has_length2() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericDataView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+ GenericPackedFieldsView<Storage>::data2()
+    const {
+
+  if ( has_data2().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = o1();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_3 = length2().length();
+    const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_4, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_5;
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_2;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericDataView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericDataView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericPackedFieldsView<Storage>::has_data2() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericPackedFieldsView<Storage>::EmbossReservedVirtualO2View
+GenericPackedFieldsView<Storage>::o2() const {
+  return
+      typename GenericPackedFieldsView<Storage>::EmbossReservedVirtualO2View(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericPackedFieldsView<Storage>::has_o2() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+ GenericPackedFieldsView<Storage>::length3()
+    const {
+
+  if ( has_length3().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = o2();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_2;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericPackedFieldsView<Storage>::has_length3() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericDataView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+ GenericPackedFieldsView<Storage>::data3()
+    const {
+
+  if ( has_data3().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = o2();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_3 = length3().length();
+    const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_4, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_5;
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_2;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericDataView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericDataView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericPackedFieldsView<Storage>::has_data3() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericPackedFieldsView<Storage>::EmbossReservedVirtualO3View
+GenericPackedFieldsView<Storage>::o3() const {
+  return
+      typename GenericPackedFieldsView<Storage>::EmbossReservedVirtualO3View(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericPackedFieldsView<Storage>::has_o3() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+ GenericPackedFieldsView<Storage>::length4()
+    const {
+
+  if ( has_length4().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = o3();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_2;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericPackedFieldsView<Storage>::has_length4() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericDataView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+ GenericPackedFieldsView<Storage>::data4()
+    const {
+
+  if ( has_data4().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = o3();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_3 = length4().length();
+    const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_4, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_5;
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_2;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericDataView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericDataView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericPackedFieldsView<Storage>::has_data4() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericPackedFieldsView<Storage>::EmbossReservedVirtualO4View
+GenericPackedFieldsView<Storage>::o4() const {
+  return
+      typename GenericPackedFieldsView<Storage>::EmbossReservedVirtualO4View(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericPackedFieldsView<Storage>::has_o4() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+ GenericPackedFieldsView<Storage>::length5()
+    const {
+
+  if ( has_length5().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = o4();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_2;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericPackedFieldsView<Storage>::has_length5() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericDataView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+ GenericPackedFieldsView<Storage>::data5()
+    const {
+
+  if ( has_data5().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = o4();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_3 = length5().length();
+    const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_4, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_5;
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_2;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericDataView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericDataView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericPackedFieldsView<Storage>::has_data5() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericPackedFieldsView<Storage>::EmbossReservedVirtualO5View
+GenericPackedFieldsView<Storage>::o5() const {
+  return
+      typename GenericPackedFieldsView<Storage>::EmbossReservedVirtualO5View(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericPackedFieldsView<Storage>::has_o5() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+ GenericPackedFieldsView<Storage>::length6()
+    const {
+
+  if ( has_length6().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = o5();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_2;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericLengthView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericPackedFieldsView<Storage>::has_length6() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericDataView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+ GenericPackedFieldsView<Storage>::data6()
+    const {
+
+  if ( has_data6().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = o5();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_3 = length6().length();
+    const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_4, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_5;
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_2;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericDataView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericDataView<typename Storage::template OffsetStorageType</**/1, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericPackedFieldsView<Storage>::has_data6() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericPackedFieldsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericPackedFieldsView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericPackedFieldsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericPackedFieldsView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace PackedFields {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1536LL)).ValueOrDefault();
+}
+}  // namespace PackedFields
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericPackedFieldsView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return PackedFields::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericPackedFieldsView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return PackedFields::MaxSizeInBytes();
+}
+
+namespace PackedFields {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL)).ValueOrDefault();
+}
+}  // namespace PackedFields
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericPackedFieldsView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return PackedFields::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericPackedFieldsView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return PackedFields::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_COMPLEX_OFFSET_EMB_H_
+
diff --git a/testdata/golden_cpp/complex_structure.emb.h b/testdata/golden_cpp/complex_structure.emb.h
new file mode 100644
index 0000000..745976a
--- /dev/null
+++ b/testdata/golden_cpp/complex_structure.emb.h
@@ -0,0 +1,4502 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_COMPLEX_STRUCTURE_EMB_H_
+#define TESTDATA_COMPLEX_STRUCTURE_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss_test {
+namespace RegisterLayout {
+
+}  // namespace RegisterLayout
+
+
+template <class Storage>
+class GenericRegisterLayoutView;
+
+namespace ArrayElement {
+
+}  // namespace ArrayElement
+
+
+template <class Storage>
+class GenericArrayElementView;
+
+namespace Complex {
+namespace EmbossReservedAnonymousField1 {
+
+}  // namespace EmbossReservedAnonymousField1
+
+
+template <class Storage>
+class GenericEmbossReservedAnonymousField1View;
+
+
+}  // namespace Complex
+
+
+template <class Storage>
+class GenericComplexView;
+
+
+
+
+
+
+
+namespace RegisterLayout {
+
+}  // namespace RegisterLayout
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericRegisterLayoutView;
+
+template <class Storage>
+class GenericRegisterLayoutView final {
+ public:
+  GenericRegisterLayoutView() : backing_() {}
+  explicit GenericRegisterLayoutView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericRegisterLayoutView(
+      const GenericRegisterLayoutView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericRegisterLayoutView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericRegisterLayoutView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericRegisterLayoutView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericRegisterLayoutView<Storage> &operator=(
+      const GenericRegisterLayoutView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_l().Known()) return false;
+    if (has_l().ValueOrDefault() && !l().Ok()) return false;
+
+
+    if (!has_h().Known()) return false;
+    if (has_h().ValueOrDefault() && !h().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBits().Known()) return false;
+    if (has_IntrinsicSizeInBits().ValueOrDefault() && !IntrinsicSizeInBits().Ok()) return false;
+
+
+    if (!has_MaxSizeInBits().Known()) return false;
+    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok()) return false;
+
+
+    if (!has_MinSizeInBits().Known()) return false;
+    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBits().Ok() &&
+           backing_.SizeInBits() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBits().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBits() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBits().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBits().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericRegisterLayoutView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_l().Known()) return false;
+    if (!emboss_reserved_local_other.has_l().Known()) return false;
+
+    if (emboss_reserved_local_other.has_l().ValueOrDefault() &&
+        !has_l().ValueOrDefault())
+      return false;
+    if (has_l().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_l().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_l().ValueOrDefault() &&
+        has_l().ValueOrDefault() &&
+        !l().Equals(emboss_reserved_local_other.l()))
+      return false;
+
+
+
+    if (!has_h().Known()) return false;
+    if (!emboss_reserved_local_other.has_h().Known()) return false;
+
+    if (emboss_reserved_local_other.has_h().ValueOrDefault() &&
+        !has_h().ValueOrDefault())
+      return false;
+    if (has_h().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_h().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_h().ValueOrDefault() &&
+        has_h().ValueOrDefault() &&
+        !h().Equals(emboss_reserved_local_other.h()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericRegisterLayoutView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_l().ValueOr(false) &&
+        !has_l().ValueOr(false))
+      return false;
+    if (has_l().ValueOr(false) &&
+        !emboss_reserved_local_other.has_l().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_l().ValueOr(false) &&
+        has_l().ValueOr(false) &&
+        !l().UncheckedEquals(emboss_reserved_local_other.l()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_h().ValueOr(false) &&
+        !has_h().ValueOr(false))
+      return false;
+    if (has_h().ValueOr(false) &&
+        !emboss_reserved_local_other.has_h().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_h().ValueOr(false) &&
+        has_h().ValueOr(false) &&
+        !h().UncheckedEquals(emboss_reserved_local_other.h()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericRegisterLayoutView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericRegisterLayoutView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericRegisterLayoutView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "l") {
+        if (!l().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "h") {
+        if (!h().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_l().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          l().IsAggregate() || l().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("l: ");
+        l().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !l().IsAggregate() && !l().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# l: UNREADABLE\n");
+      }
+    }
+
+    if (has_h().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          h().IsAggregate() || h().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("h: ");
+        h().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !h().IsAggregate() && !h().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# h: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ l() const;
+  ::emboss::support::Maybe<bool> has_l() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 4>>
+
+ h() const;
+  ::emboss::support::Maybe<bool> has_h() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView IntrinsicSizeInBits() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBitsView() {}
+    EmbossReservedDollarVirtualMaxSizeInBitsView(const EmbossReservedDollarVirtualMaxSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView(EmbossReservedDollarVirtualMaxSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(const EmbossReservedDollarVirtualMaxSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(EmbossReservedDollarVirtualMaxSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBitsView MaxSizeInBits() {
+    return EmbossReservedDollarVirtualMaxSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBitsView() {}
+    EmbossReservedDollarVirtualMinSizeInBitsView(const EmbossReservedDollarVirtualMinSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView(EmbossReservedDollarVirtualMinSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(const EmbossReservedDollarVirtualMinSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(EmbossReservedDollarVirtualMinSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBitsView MinSizeInBits() {
+    return EmbossReservedDollarVirtualMinSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericRegisterLayoutView;
+};
+using RegisterLayoutView =
+    GenericRegisterLayoutView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using RegisterLayoutWriter =
+    GenericRegisterLayoutView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericRegisterLayoutView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericRegisterLayoutView<
+    GenericRegisterLayoutView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericRegisterLayoutView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeRegisterLayoutView( T &&emboss_reserved_local_arg) {
+  return GenericRegisterLayoutView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericRegisterLayoutView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeRegisterLayoutView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericRegisterLayoutView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericRegisterLayoutView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedRegisterLayoutView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericRegisterLayoutView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+namespace ArrayElement {
+
+}  // namespace ArrayElement
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericArrayElementView;
+
+template <class Storage>
+class GenericArrayElementView final {
+ public:
+  GenericArrayElementView() : backing_() {}
+  explicit GenericArrayElementView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericArrayElementView(
+      const GenericArrayElementView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericArrayElementView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericArrayElementView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericArrayElementView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericArrayElementView<Storage> &operator=(
+      const GenericArrayElementView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_a().Known()) return false;
+    if (has_a().ValueOrDefault() && !a().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericArrayElementView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_a().Known()) return false;
+    if (!emboss_reserved_local_other.has_a().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        !has_a().ValueOrDefault())
+      return false;
+    if (has_a().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        has_a().ValueOrDefault() &&
+        !a().Equals(emboss_reserved_local_other.a()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericArrayElementView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        !has_a().ValueOr(false))
+      return false;
+    if (has_a().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        has_a().ValueOr(false) &&
+        !a().UncheckedEquals(emboss_reserved_local_other.a()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericArrayElementView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericArrayElementView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericArrayElementView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "a") {
+        if (!a().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_a().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a().IsAggregate() || a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a: ");
+        a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a().IsAggregate() && !a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss_test::GenericRegisterLayoutView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ a() const;
+  ::emboss::support::Maybe<bool> has_a() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericArrayElementView;
+};
+using ArrayElementView =
+    GenericArrayElementView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ArrayElementWriter =
+    GenericArrayElementView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericArrayElementView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericArrayElementView<
+    GenericArrayElementView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericArrayElementView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeArrayElementView( T &&emboss_reserved_local_arg) {
+  return GenericArrayElementView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericArrayElementView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeArrayElementView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericArrayElementView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericArrayElementView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedArrayElementView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericArrayElementView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+namespace Complex {
+
+
+
+
+
+
+namespace EmbossReservedAnonymousField1 {
+
+}  // namespace EmbossReservedAnonymousField1
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View;
+
+template <class Storage>
+class GenericEmbossReservedAnonymousField1View final {
+ public:
+  GenericEmbossReservedAnonymousField1View() : backing_() {}
+  explicit GenericEmbossReservedAnonymousField1View(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEmbossReservedAnonymousField1View(
+      const GenericEmbossReservedAnonymousField1View<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericEmbossReservedAnonymousField1View(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericEmbossReservedAnonymousField1View(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEmbossReservedAnonymousField1View<Storage> &operator=(
+      const GenericEmbossReservedAnonymousField1View<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_a0().Known()) return false;
+    if (has_a0().ValueOrDefault() && !a0().Ok()) return false;
+
+
+    if (!has_s0().Known()) return false;
+    if (has_s0().ValueOrDefault() && !s0().Ok()) return false;
+
+
+    if (!has_l0().Known()) return false;
+    if (has_l0().ValueOrDefault() && !l0().Ok()) return false;
+
+
+    if (!has_h0().Known()) return false;
+    if (has_h0().ValueOrDefault() && !h0().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBits().Known()) return false;
+    if (has_IntrinsicSizeInBits().ValueOrDefault() && !IntrinsicSizeInBits().Ok()) return false;
+
+
+    if (!has_MaxSizeInBits().Known()) return false;
+    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok()) return false;
+
+
+    if (!has_MinSizeInBits().Known()) return false;
+    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBits().Ok() &&
+           backing_.SizeInBits() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBits().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBits() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBits().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBits().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_a0().Known()) return false;
+    if (!emboss_reserved_local_other.has_a0().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a0().ValueOrDefault() &&
+        !has_a0().ValueOrDefault())
+      return false;
+    if (has_a0().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a0().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a0().ValueOrDefault() &&
+        has_a0().ValueOrDefault() &&
+        !a0().Equals(emboss_reserved_local_other.a0()))
+      return false;
+
+
+
+    if (!has_s0().Known()) return false;
+    if (!emboss_reserved_local_other.has_s0().Known()) return false;
+
+    if (emboss_reserved_local_other.has_s0().ValueOrDefault() &&
+        !has_s0().ValueOrDefault())
+      return false;
+    if (has_s0().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_s0().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_s0().ValueOrDefault() &&
+        has_s0().ValueOrDefault() &&
+        !s0().Equals(emboss_reserved_local_other.s0()))
+      return false;
+
+
+
+    if (!has_l0().Known()) return false;
+    if (!emboss_reserved_local_other.has_l0().Known()) return false;
+
+    if (emboss_reserved_local_other.has_l0().ValueOrDefault() &&
+        !has_l0().ValueOrDefault())
+      return false;
+    if (has_l0().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_l0().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_l0().ValueOrDefault() &&
+        has_l0().ValueOrDefault() &&
+        !l0().Equals(emboss_reserved_local_other.l0()))
+      return false;
+
+
+
+    if (!has_h0().Known()) return false;
+    if (!emboss_reserved_local_other.has_h0().Known()) return false;
+
+    if (emboss_reserved_local_other.has_h0().ValueOrDefault() &&
+        !has_h0().ValueOrDefault())
+      return false;
+    if (has_h0().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_h0().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_h0().ValueOrDefault() &&
+        has_h0().ValueOrDefault() &&
+        !h0().Equals(emboss_reserved_local_other.h0()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_a0().ValueOr(false) &&
+        !has_a0().ValueOr(false))
+      return false;
+    if (has_a0().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a0().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a0().ValueOr(false) &&
+        has_a0().ValueOr(false) &&
+        !a0().UncheckedEquals(emboss_reserved_local_other.a0()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_s0().ValueOr(false) &&
+        !has_s0().ValueOr(false))
+      return false;
+    if (has_s0().ValueOr(false) &&
+        !emboss_reserved_local_other.has_s0().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_s0().ValueOr(false) &&
+        has_s0().ValueOr(false) &&
+        !s0().UncheckedEquals(emboss_reserved_local_other.s0()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_l0().ValueOr(false) &&
+        !has_l0().ValueOr(false))
+      return false;
+    if (has_l0().ValueOr(false) &&
+        !emboss_reserved_local_other.has_l0().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_l0().ValueOr(false) &&
+        has_l0().ValueOr(false) &&
+        !l0().UncheckedEquals(emboss_reserved_local_other.l0()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_h0().ValueOr(false) &&
+        !has_h0().ValueOr(false))
+      return false;
+    if (has_h0().ValueOr(false) &&
+        !emboss_reserved_local_other.has_h0().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_h0().ValueOr(false) &&
+        has_h0().ValueOr(false) &&
+        !h0().UncheckedEquals(emboss_reserved_local_other.h0()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "a0") {
+        if (!a0().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "s0") {
+        if (!s0().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "l0") {
+        if (!l0().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "h0") {
+        if (!h0().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_a0().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a0().IsAggregate() || a0().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a0: ");
+        a0().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a0().IsAggregate() && !a0().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a0: UNREADABLE\n");
+      }
+    }
+
+    if (has_s0().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          s0().IsAggregate() || s0().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("s0: ");
+        s0().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !s0().IsAggregate() && !s0().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# s0: UNREADABLE\n");
+      }
+    }
+
+    if (has_l0().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          l0().IsAggregate() || l0().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("l0: ");
+        l0().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !l0().IsAggregate() && !l0().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# l0: UNREADABLE\n");
+      }
+    }
+
+    if (has_h0().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          h0().IsAggregate() || h0().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("h0: ");
+        h0().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !h0().IsAggregate() && !h0().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# h0: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ a0() const;
+  ::emboss::support::Maybe<bool> has_a0() const;
+
+ public:
+  typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 7>>
+
+ s0() const;
+  ::emboss::support::Maybe<bool> has_s0() const;
+
+ public:
+  typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ l0() const;
+  ::emboss::support::Maybe<bool> has_l0() const;
+
+ public:
+  typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 4>>
+
+ h0() const;
+  ::emboss::support::Maybe<bool> has_h0() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView IntrinsicSizeInBits() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBitsView() {}
+    EmbossReservedDollarVirtualMaxSizeInBitsView(const EmbossReservedDollarVirtualMaxSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView(EmbossReservedDollarVirtualMaxSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(const EmbossReservedDollarVirtualMaxSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(EmbossReservedDollarVirtualMaxSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBitsView MaxSizeInBits() {
+    return EmbossReservedDollarVirtualMaxSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBitsView() {}
+    EmbossReservedDollarVirtualMinSizeInBitsView(const EmbossReservedDollarVirtualMinSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView(EmbossReservedDollarVirtualMinSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(const EmbossReservedDollarVirtualMinSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(EmbossReservedDollarVirtualMinSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBitsView MinSizeInBits() {
+    return EmbossReservedDollarVirtualMinSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericEmbossReservedAnonymousField1View;
+};
+using EmbossReservedAnonymousField1View =
+    GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using EmbossReservedAnonymousField1Writer =
+    GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View<
+    GenericEmbossReservedAnonymousField1View<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericEmbossReservedAnonymousField1View<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeEmbossReservedAnonymousField1View( T &&emboss_reserved_local_arg) {
+  return GenericEmbossReservedAnonymousField1View<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeEmbossReservedAnonymousField1View( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericEmbossReservedAnonymousField1View<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedEmbossReservedAnonymousField1View(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericEmbossReservedAnonymousField1View<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+}  // namespace Complex
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericComplexView;
+
+template <class Storage>
+class GenericComplexView final {
+ public:
+  GenericComplexView() : backing_() {}
+  explicit GenericComplexView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericComplexView(
+      const GenericComplexView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericComplexView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericComplexView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericComplexView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericComplexView<Storage> &operator=(
+      const GenericComplexView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_s().Known()) return false;
+    if (has_s().ValueOrDefault() && !s().Ok()) return false;
+
+
+    if (!has_u().Known()) return false;
+    if (has_u().ValueOrDefault() && !u().Ok()) return false;
+
+
+    if (!has_i().Known()) return false;
+    if (has_i().ValueOrDefault() && !i().Ok()) return false;
+
+
+    if (!has_b().Known()) return false;
+    if (has_b().ValueOrDefault() && !b().Ok()) return false;
+
+
+    if (!has_a().Known()) return false;
+    if (has_a().ValueOrDefault() && !a().Ok()) return false;
+
+
+    if (!has_emboss_reserved_anonymous_field_1().Known()) return false;
+    if (has_emboss_reserved_anonymous_field_1().ValueOrDefault() && !emboss_reserved_anonymous_field_1().Ok()) return false;
+
+
+    if (!has_a0().Known()) return false;
+    if (has_a0().ValueOrDefault() && !a0().Ok()) return false;
+
+
+    if (!has_s0().Known()) return false;
+    if (has_s0().ValueOrDefault() && !s0().Ok()) return false;
+
+
+    if (!has_l0().Known()) return false;
+    if (has_l0().ValueOrDefault() && !l0().Ok()) return false;
+
+
+    if (!has_h0().Known()) return false;
+    if (has_h0().ValueOrDefault() && !h0().Ok()) return false;
+
+
+    if (!has_e1().Known()) return false;
+    if (has_e1().ValueOrDefault() && !e1().Ok()) return false;
+
+
+    if (!has_e2().Known()) return false;
+    if (has_e2().ValueOrDefault() && !e2().Ok()) return false;
+
+
+    if (!has_b2().Known()) return false;
+    if (has_b2().ValueOrDefault() && !b2().Ok()) return false;
+
+
+    if (!has_e3().Known()) return false;
+    if (has_e3().ValueOrDefault() && !e3().Ok()) return false;
+
+
+    if (!has_e4().Known()) return false;
+    if (has_e4().ValueOrDefault() && !e4().Ok()) return false;
+
+
+    if (!has_e5().Known()) return false;
+    if (has_e5().ValueOrDefault() && !e5().Ok()) return false;
+
+
+    if (!has_e0().Known()) return false;
+    if (has_e0().ValueOrDefault() && !e0().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericComplexView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_s().Known()) return false;
+    if (!emboss_reserved_local_other.has_s().Known()) return false;
+
+    if (emboss_reserved_local_other.has_s().ValueOrDefault() &&
+        !has_s().ValueOrDefault())
+      return false;
+    if (has_s().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_s().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_s().ValueOrDefault() &&
+        has_s().ValueOrDefault() &&
+        !s().Equals(emboss_reserved_local_other.s()))
+      return false;
+
+
+
+    if (!has_u().Known()) return false;
+    if (!emboss_reserved_local_other.has_u().Known()) return false;
+
+    if (emboss_reserved_local_other.has_u().ValueOrDefault() &&
+        !has_u().ValueOrDefault())
+      return false;
+    if (has_u().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_u().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_u().ValueOrDefault() &&
+        has_u().ValueOrDefault() &&
+        !u().Equals(emboss_reserved_local_other.u()))
+      return false;
+
+
+
+    if (!has_i().Known()) return false;
+    if (!emboss_reserved_local_other.has_i().Known()) return false;
+
+    if (emboss_reserved_local_other.has_i().ValueOrDefault() &&
+        !has_i().ValueOrDefault())
+      return false;
+    if (has_i().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_i().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_i().ValueOrDefault() &&
+        has_i().ValueOrDefault() &&
+        !i().Equals(emboss_reserved_local_other.i()))
+      return false;
+
+
+
+    if (!has_b().Known()) return false;
+    if (!emboss_reserved_local_other.has_b().Known()) return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        !has_b().ValueOrDefault())
+      return false;
+    if (has_b().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_b().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        has_b().ValueOrDefault() &&
+        !b().Equals(emboss_reserved_local_other.b()))
+      return false;
+
+
+
+    if (!has_a().Known()) return false;
+    if (!emboss_reserved_local_other.has_a().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        !has_a().ValueOrDefault())
+      return false;
+    if (has_a().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        has_a().ValueOrDefault() &&
+        !a().Equals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (!has_emboss_reserved_anonymous_field_1().Known()) return false;
+    if (!emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().Known()) return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        !has_emboss_reserved_anonymous_field_1().ValueOrDefault())
+      return false;
+    if (has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        !emboss_reserved_anonymous_field_1().Equals(emboss_reserved_local_other.emboss_reserved_anonymous_field_1()))
+      return false;
+
+
+
+    if (!has_e1().Known()) return false;
+    if (!emboss_reserved_local_other.has_e1().Known()) return false;
+
+    if (emboss_reserved_local_other.has_e1().ValueOrDefault() &&
+        !has_e1().ValueOrDefault())
+      return false;
+    if (has_e1().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_e1().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_e1().ValueOrDefault() &&
+        has_e1().ValueOrDefault() &&
+        !e1().Equals(emboss_reserved_local_other.e1()))
+      return false;
+
+
+
+    if (!has_e2().Known()) return false;
+    if (!emboss_reserved_local_other.has_e2().Known()) return false;
+
+    if (emboss_reserved_local_other.has_e2().ValueOrDefault() &&
+        !has_e2().ValueOrDefault())
+      return false;
+    if (has_e2().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_e2().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_e2().ValueOrDefault() &&
+        has_e2().ValueOrDefault() &&
+        !e2().Equals(emboss_reserved_local_other.e2()))
+      return false;
+
+
+
+    if (!has_b2().Known()) return false;
+    if (!emboss_reserved_local_other.has_b2().Known()) return false;
+
+    if (emboss_reserved_local_other.has_b2().ValueOrDefault() &&
+        !has_b2().ValueOrDefault())
+      return false;
+    if (has_b2().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_b2().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_b2().ValueOrDefault() &&
+        has_b2().ValueOrDefault() &&
+        !b2().Equals(emboss_reserved_local_other.b2()))
+      return false;
+
+
+
+    if (!has_e3().Known()) return false;
+    if (!emboss_reserved_local_other.has_e3().Known()) return false;
+
+    if (emboss_reserved_local_other.has_e3().ValueOrDefault() &&
+        !has_e3().ValueOrDefault())
+      return false;
+    if (has_e3().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_e3().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_e3().ValueOrDefault() &&
+        has_e3().ValueOrDefault() &&
+        !e3().Equals(emboss_reserved_local_other.e3()))
+      return false;
+
+
+
+    if (!has_e4().Known()) return false;
+    if (!emboss_reserved_local_other.has_e4().Known()) return false;
+
+    if (emboss_reserved_local_other.has_e4().ValueOrDefault() &&
+        !has_e4().ValueOrDefault())
+      return false;
+    if (has_e4().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_e4().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_e4().ValueOrDefault() &&
+        has_e4().ValueOrDefault() &&
+        !e4().Equals(emboss_reserved_local_other.e4()))
+      return false;
+
+
+
+    if (!has_e5().Known()) return false;
+    if (!emboss_reserved_local_other.has_e5().Known()) return false;
+
+    if (emboss_reserved_local_other.has_e5().ValueOrDefault() &&
+        !has_e5().ValueOrDefault())
+      return false;
+    if (has_e5().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_e5().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_e5().ValueOrDefault() &&
+        has_e5().ValueOrDefault() &&
+        !e5().Equals(emboss_reserved_local_other.e5()))
+      return false;
+
+
+
+    if (!has_e0().Known()) return false;
+    if (!emboss_reserved_local_other.has_e0().Known()) return false;
+
+    if (emboss_reserved_local_other.has_e0().ValueOrDefault() &&
+        !has_e0().ValueOrDefault())
+      return false;
+    if (has_e0().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_e0().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_e0().ValueOrDefault() &&
+        has_e0().ValueOrDefault() &&
+        !e0().Equals(emboss_reserved_local_other.e0()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericComplexView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_s().ValueOr(false) &&
+        !has_s().ValueOr(false))
+      return false;
+    if (has_s().ValueOr(false) &&
+        !emboss_reserved_local_other.has_s().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_s().ValueOr(false) &&
+        has_s().ValueOr(false) &&
+        !s().UncheckedEquals(emboss_reserved_local_other.s()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_u().ValueOr(false) &&
+        !has_u().ValueOr(false))
+      return false;
+    if (has_u().ValueOr(false) &&
+        !emboss_reserved_local_other.has_u().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_u().ValueOr(false) &&
+        has_u().ValueOr(false) &&
+        !u().UncheckedEquals(emboss_reserved_local_other.u()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_i().ValueOr(false) &&
+        !has_i().ValueOr(false))
+      return false;
+    if (has_i().ValueOr(false) &&
+        !emboss_reserved_local_other.has_i().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_i().ValueOr(false) &&
+        has_i().ValueOr(false) &&
+        !i().UncheckedEquals(emboss_reserved_local_other.i()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        !has_b().ValueOr(false))
+      return false;
+    if (has_b().ValueOr(false) &&
+        !emboss_reserved_local_other.has_b().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        has_b().ValueOr(false) &&
+        !b().UncheckedEquals(emboss_reserved_local_other.b()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        !has_a().ValueOr(false))
+      return false;
+    if (has_a().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        has_a().ValueOr(false) &&
+        !a().UncheckedEquals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        !has_emboss_reserved_anonymous_field_1().ValueOr(false))
+      return false;
+    if (has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        !emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        !emboss_reserved_anonymous_field_1().UncheckedEquals(emboss_reserved_local_other.emboss_reserved_anonymous_field_1()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_e1().ValueOr(false) &&
+        !has_e1().ValueOr(false))
+      return false;
+    if (has_e1().ValueOr(false) &&
+        !emboss_reserved_local_other.has_e1().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_e1().ValueOr(false) &&
+        has_e1().ValueOr(false) &&
+        !e1().UncheckedEquals(emboss_reserved_local_other.e1()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_e2().ValueOr(false) &&
+        !has_e2().ValueOr(false))
+      return false;
+    if (has_e2().ValueOr(false) &&
+        !emboss_reserved_local_other.has_e2().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_e2().ValueOr(false) &&
+        has_e2().ValueOr(false) &&
+        !e2().UncheckedEquals(emboss_reserved_local_other.e2()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_b2().ValueOr(false) &&
+        !has_b2().ValueOr(false))
+      return false;
+    if (has_b2().ValueOr(false) &&
+        !emboss_reserved_local_other.has_b2().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_b2().ValueOr(false) &&
+        has_b2().ValueOr(false) &&
+        !b2().UncheckedEquals(emboss_reserved_local_other.b2()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_e3().ValueOr(false) &&
+        !has_e3().ValueOr(false))
+      return false;
+    if (has_e3().ValueOr(false) &&
+        !emboss_reserved_local_other.has_e3().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_e3().ValueOr(false) &&
+        has_e3().ValueOr(false) &&
+        !e3().UncheckedEquals(emboss_reserved_local_other.e3()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_e4().ValueOr(false) &&
+        !has_e4().ValueOr(false))
+      return false;
+    if (has_e4().ValueOr(false) &&
+        !emboss_reserved_local_other.has_e4().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_e4().ValueOr(false) &&
+        has_e4().ValueOr(false) &&
+        !e4().UncheckedEquals(emboss_reserved_local_other.e4()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_e5().ValueOr(false) &&
+        !has_e5().ValueOr(false))
+      return false;
+    if (has_e5().ValueOr(false) &&
+        !emboss_reserved_local_other.has_e5().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_e5().ValueOr(false) &&
+        has_e5().ValueOr(false) &&
+        !e5().UncheckedEquals(emboss_reserved_local_other.e5()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_e0().ValueOr(false) &&
+        !has_e0().ValueOr(false))
+      return false;
+    if (has_e0().ValueOr(false) &&
+        !emboss_reserved_local_other.has_e0().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_e0().ValueOr(false) &&
+        has_e0().ValueOr(false) &&
+        !e0().UncheckedEquals(emboss_reserved_local_other.e0()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericComplexView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericComplexView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericComplexView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "s") {
+        if (!s().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "u") {
+        if (!u().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "i") {
+        if (!i().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "b") {
+        if (!b().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "a") {
+        if (!a().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "a0") {
+        if (!a0().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "s0") {
+        if (!s0().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "l0") {
+        if (!l0().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "h0") {
+        if (!h0().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "e1") {
+        if (!e1().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "e2") {
+        if (!e2().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "b2") {
+        if (!b2().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "e3") {
+        if (!e3().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "e4") {
+        if (!e4().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "e5") {
+        if (!e5().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "e0") {
+        if (!e0().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_s().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          s().IsAggregate() || s().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("s: ");
+        s().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !s().IsAggregate() && !s().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# s: UNREADABLE\n");
+      }
+    }
+
+    if (has_u().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          u().IsAggregate() || u().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("u: ");
+        u().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !u().IsAggregate() && !u().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# u: UNREADABLE\n");
+      }
+    }
+
+    if (has_i().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          i().IsAggregate() || i().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("i: ");
+        i().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !i().IsAggregate() && !i().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# i: UNREADABLE\n");
+      }
+    }
+
+    if (has_b().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b().IsAggregate() || b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("b: ");
+        b().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !b().IsAggregate() && !b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b: UNREADABLE\n");
+      }
+    }
+
+    if (has_a().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a().IsAggregate() || a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a: ");
+        a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a().IsAggregate() && !a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a: UNREADABLE\n");
+      }
+    }
+
+    if (has_a0().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a0().IsAggregate() || a0().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a0: ");
+        a0().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a0().IsAggregate() && !a0().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a0: UNREADABLE\n");
+      }
+    }
+
+    if (has_s0().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          s0().IsAggregate() || s0().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("s0: ");
+        s0().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !s0().IsAggregate() && !s0().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# s0: UNREADABLE\n");
+      }
+    }
+
+    if (has_l0().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          l0().IsAggregate() || l0().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("l0: ");
+        l0().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !l0().IsAggregate() && !l0().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# l0: UNREADABLE\n");
+      }
+    }
+
+    if (has_h0().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          h0().IsAggregate() || h0().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("h0: ");
+        h0().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !h0().IsAggregate() && !h0().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# h0: UNREADABLE\n");
+      }
+    }
+
+    if (has_e1().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          e1().IsAggregate() || e1().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("e1: ");
+        e1().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !e1().IsAggregate() && !e1().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# e1: UNREADABLE\n");
+      }
+    }
+
+    if (has_e2().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          e2().IsAggregate() || e2().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("e2: ");
+        e2().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !e2().IsAggregate() && !e2().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# e2: UNREADABLE\n");
+      }
+    }
+
+    if (has_b2().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b2().IsAggregate() || b2().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("b2: ");
+        b2().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !b2().IsAggregate() && !b2().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b2: UNREADABLE\n");
+      }
+    }
+
+    if (has_e3().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          e3().IsAggregate() || e3().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("e3: ");
+        e3().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !e3().IsAggregate() && !e3().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# e3: UNREADABLE\n");
+      }
+    }
+
+    if (has_e4().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          e4().IsAggregate() || e4().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("e4: ");
+        e4().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !e4().IsAggregate() && !e4().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# e4: UNREADABLE\n");
+      }
+    }
+
+    if (has_e5().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          e5().IsAggregate() || e5().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("e5: ");
+        e5().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !e5().IsAggregate() && !e5().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# e5: UNREADABLE\n");
+      }
+    }
+
+    if (has_e0().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          e0().IsAggregate() || e0().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("e0: ");
+        e0().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !e0().IsAggregate() && !e0().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# e0: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ s() const;
+  ::emboss::support::Maybe<bool> has_s() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 64>>
+
+ u() const;
+  ::emboss::support::Maybe<bool> has_u() const;
+
+ public:
+  typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 64>>
+
+ i() const;
+  ::emboss::support::Maybe<bool> has_i() const;
+
+ public:
+  typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 64>>
+
+ b() const;
+  ::emboss::support::Maybe<bool> has_b() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::support::GenericArrayView<
+    typename ::emboss_test::GenericArrayElementView<typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/4, 0>::template OffsetStorageType</**/1, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/4, 0>, 1,
+    8 >
+
+, typename Storage::template OffsetStorageType</**/0, 1>, 4,
+    8 >
+
+ a() const;
+  ::emboss::support::Maybe<bool> has_a() const;
+
+ private:
+  typename ::emboss_test::Complex::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ emboss_reserved_anonymous_field_1() const;
+  ::emboss::support::Maybe<bool> has_emboss_reserved_anonymous_field_1() const;
+
+ public:
+  auto a0() const -> decltype(this->emboss_reserved_anonymous_field_1().a0()) {
+   return has_a0().ValueOrDefault() ? emboss_reserved_anonymous_field_1().a0()
+                                          : decltype(this->emboss_reserved_anonymous_field_1().a0())();
+  }
+  ::emboss::support::Maybe<bool> has_a0() const;
+
+ public:
+  auto s0() const -> decltype(this->emboss_reserved_anonymous_field_1().s0()) {
+   return has_s0().ValueOrDefault() ? emboss_reserved_anonymous_field_1().s0()
+                                          : decltype(this->emboss_reserved_anonymous_field_1().s0())();
+  }
+  ::emboss::support::Maybe<bool> has_s0() const;
+
+ public:
+  auto l0() const -> decltype(this->emboss_reserved_anonymous_field_1().l0()) {
+   return has_l0().ValueOrDefault() ? emboss_reserved_anonymous_field_1().l0()
+                                          : decltype(this->emboss_reserved_anonymous_field_1().l0())();
+  }
+  ::emboss::support::Maybe<bool> has_l0() const;
+
+ public:
+  auto h0() const -> decltype(this->emboss_reserved_anonymous_field_1().h0()) {
+   return has_h0().ValueOrDefault() ? emboss_reserved_anonymous_field_1().h0()
+                                          : decltype(this->emboss_reserved_anonymous_field_1().h0())();
+  }
+  ::emboss::support::Maybe<bool> has_h0() const;
+
+ public:
+  typename ::emboss_test::GenericArrayElementView<typename Storage::template OffsetStorageType</**/0, 2>>
+
+ e1() const;
+  ::emboss::support::Maybe<bool> has_e1() const;
+
+ public:
+  typename ::emboss_test::GenericArrayElementView<typename Storage::template OffsetStorageType</**/0, 3>>
+
+ e2() const;
+  ::emboss::support::Maybe<bool> has_e2() const;
+
+ public:
+  typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 8>>
+
+ b2() const;
+  ::emboss::support::Maybe<bool> has_b2() const;
+
+ public:
+  typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 8>>
+
+ e3() const;
+  ::emboss::support::Maybe<bool> has_e3() const;
+
+ public:
+  typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 5>>, 8>>
+
+ e4() const;
+  ::emboss::support::Maybe<bool> has_e4() const;
+
+ public:
+  typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 8>>
+
+ e5() const;
+  ::emboss::support::Maybe<bool> has_e5() const;
+
+ public:
+  typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ e0() const;
+  ::emboss::support::Maybe<bool> has_e0() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericComplexView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.s();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Product</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_3);
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_4, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_6 = view_.a0();
+      const auto emboss_reserved_local_subexpr_7 = (emboss_reserved_local_subexpr_6.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_6.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_8 = ::emboss::support::GreaterThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_7, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(128LL)));
+      const auto emboss_reserved_local_subexpr_9 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_8, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_10 = ::emboss::support::LessThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_7, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(128LL)));
+      const auto emboss_reserved_local_subexpr_11 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_10, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_12 = view_.b2();
+      const auto emboss_reserved_local_subexpr_13 = (emboss_reserved_local_subexpr_12.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_12.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_14 = ::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_13, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(25LL)));
+      const auto emboss_reserved_local_subexpr_15 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_14, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_16 = ::emboss::support::GreaterThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)));
+      const auto emboss_reserved_local_subexpr_17 = ::emboss::support::GreaterThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_7, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(80LL)));
+      const auto emboss_reserved_local_subexpr_18 = view_.e3();
+      const auto emboss_reserved_local_subexpr_19 = (emboss_reserved_local_subexpr_18.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_18.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_20 = ::emboss::support::GreaterThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_19, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(128LL)));
+      const auto emboss_reserved_local_subexpr_21 = ::emboss::support::LessThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_13, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(50LL)));
+      const auto emboss_reserved_local_subexpr_22 = ::emboss::support::Choice</**/bool, bool, bool, bool, bool>(emboss_reserved_local_subexpr_17, emboss_reserved_local_subexpr_20, emboss_reserved_local_subexpr_21);
+      const auto emboss_reserved_local_subexpr_23 = ::emboss::support::And</**/bool, bool, bool, bool>(emboss_reserved_local_subexpr_16, emboss_reserved_local_subexpr_22);
+      const auto emboss_reserved_local_subexpr_24 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_23, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_25 = ::emboss::support::GreaterThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
+      const auto emboss_reserved_local_subexpr_26 = view_.e4();
+      const auto emboss_reserved_local_subexpr_27 = (emboss_reserved_local_subexpr_26.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_26.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_28 = ::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_27, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_29 = ::emboss::support::And</**/bool, bool, bool, bool>(emboss_reserved_local_subexpr_25, emboss_reserved_local_subexpr_28);
+      const auto emboss_reserved_local_subexpr_30 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_29, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(7LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_31 = ::emboss::support::LessThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)));
+      const auto emboss_reserved_local_subexpr_32 = ::emboss::support::LessThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_7, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)));
+      const auto emboss_reserved_local_subexpr_33 = ::emboss::support::Or</**/bool, bool, bool, bool>(emboss_reserved_local_subexpr_31, emboss_reserved_local_subexpr_32);
+      const auto emboss_reserved_local_subexpr_34 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_33, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_35 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(9LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(9LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(9LL)), emboss_reserved_local_subexpr_5, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)), emboss_reserved_local_subexpr_9, emboss_reserved_local_subexpr_11, emboss_reserved_local_subexpr_15, emboss_reserved_local_subexpr_24, emboss_reserved_local_subexpr_30, emboss_reserved_local_subexpr_34);
+
+      return emboss_reserved_local_subexpr_35;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericComplexView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericComplexView;
+};
+using ComplexView =
+    GenericComplexView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ComplexWriter =
+    GenericComplexView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericComplexView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericComplexView<
+    GenericComplexView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericComplexView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeComplexView( T &&emboss_reserved_local_arg) {
+  return GenericComplexView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericComplexView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeComplexView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericComplexView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericComplexView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedComplexView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericComplexView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace RegisterLayout {
+
+}  // namespace RegisterLayout
+
+
+template <class Storage>
+inline typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericRegisterLayoutView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRegisterLayoutView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericRegisterLayoutView<Storage>::l()
+    const {
+
+  if ( has_l().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRegisterLayoutView<Storage>::has_l() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 4>>
+
+ GenericRegisterLayoutView<Storage>::h()
+    const {
+
+  if ( has_h().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 4>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   4>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 4>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRegisterLayoutView<Storage>::has_h() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace RegisterLayout {
+inline constexpr ::std::int32_t IntrinsicSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace RegisterLayout
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRegisterLayoutView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
+  return RegisterLayout::IntrinsicSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRegisterLayoutView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
+  return RegisterLayout::IntrinsicSizeInBits();
+}
+
+namespace RegisterLayout {
+inline constexpr ::std::int32_t MaxSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace RegisterLayout
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRegisterLayoutView<Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
+  return RegisterLayout::MaxSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRegisterLayoutView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
+  return RegisterLayout::MaxSizeInBits();
+}
+
+namespace RegisterLayout {
+inline constexpr ::std::int32_t MinSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace RegisterLayout
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRegisterLayoutView<Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
+  return RegisterLayout::MinSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRegisterLayoutView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
+  return RegisterLayout::MinSizeInBits();
+}
+namespace ArrayElement {
+
+}  // namespace ArrayElement
+
+
+template <class Storage>
+inline typename ::emboss_test::GenericRegisterLayoutView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericArrayElementView<Storage>::a()
+    const {
+
+  if ( has_a().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss_test::GenericRegisterLayoutView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss_test::GenericRegisterLayoutView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericArrayElementView<Storage>::has_a() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace ArrayElement {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace ArrayElement
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericArrayElementView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return ArrayElement::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericArrayElementView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return ArrayElement::IntrinsicSizeInBytes();
+}
+
+namespace ArrayElement {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace ArrayElement
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericArrayElementView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return ArrayElement::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericArrayElementView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return ArrayElement::MaxSizeInBytes();
+}
+
+namespace ArrayElement {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace ArrayElement
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericArrayElementView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return ArrayElement::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericArrayElementView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return ArrayElement::MinSizeInBytes();
+}
+namespace Complex {
+namespace EmbossReservedAnonymousField1 {
+
+}  // namespace EmbossReservedAnonymousField1
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericEmbossReservedAnonymousField1View<Storage>::a0()
+    const {
+
+  if ( has_a0().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField1View<Storage>::has_a0() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 7>>
+
+ GenericEmbossReservedAnonymousField1View<Storage>::s0()
+    const {
+
+  if ( has_s0().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(7LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 7>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   7>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 7>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField1View<Storage>::has_s0() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericEmbossReservedAnonymousField1View<Storage>::l0()
+    const {
+
+  if ( has_l0().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField1View<Storage>::has_l0() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 4>>
+
+ GenericEmbossReservedAnonymousField1View<Storage>::h0()
+    const {
+
+  if ( has_h0().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 4>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   4>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 4>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField1View<Storage>::has_h0() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace EmbossReservedAnonymousField1 {
+inline constexpr ::std::int32_t IntrinsicSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField1
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField1::IntrinsicSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField1::IntrinsicSizeInBits();
+}
+
+namespace EmbossReservedAnonymousField1 {
+inline constexpr ::std::int32_t MaxSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField1
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField1::MaxSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField1::MaxSizeInBits();
+}
+
+namespace EmbossReservedAnonymousField1 {
+inline constexpr ::std::int32_t MinSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField1
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField1::MinSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField1::MinSizeInBits();
+}
+
+}  // namespace Complex
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericComplexView<Storage>::s()
+    const {
+
+  if ( has_s().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericComplexView<Storage>::has_s() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 64>>
+
+ GenericComplexView<Storage>::u()
+    const {
+
+  if ( has_u().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 64>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 64>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericComplexView<Storage>::has_u() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 64>>
+
+ GenericComplexView<Storage>::i()
+    const {
+
+  if ( has_i().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 64>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 64>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericComplexView<Storage>::has_i() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 64>>
+
+ GenericComplexView<Storage>::b()
+    const {
+
+  if ( has_b().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 64>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 64>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericComplexView<Storage>::has_b() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::support::GenericArrayView<
+    typename ::emboss_test::GenericArrayElementView<typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/4, 0>::template OffsetStorageType</**/1, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/4, 0>, 1,
+    8 >
+
+, typename Storage::template OffsetStorageType</**/0, 1>, 4,
+    8 >
+
+ GenericComplexView<Storage>::a()
+    const {
+
+  if ( has_a().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = s();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Product</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)));
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_3;
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::support::GenericArrayView<
+    typename ::emboss_test::GenericArrayElementView<typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/4, 0>::template OffsetStorageType</**/1, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/4, 0>, 1,
+    8 >
+
+, typename Storage::template OffsetStorageType</**/0, 1>, 4,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::support::GenericArrayView<
+    typename ::emboss_test::GenericArrayElementView<typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/4, 0>::template OffsetStorageType</**/1, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/4, 0>, 1,
+    8 >
+
+, typename Storage::template OffsetStorageType</**/0, 1>, 4,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericComplexView<Storage>::has_a() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss_test::Complex::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericComplexView<Storage>::emboss_reserved_anonymous_field_1()
+    const {
+
+  if ( has_emboss_reserved_anonymous_field_1().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss_test::Complex::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss_test::Complex::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericComplexView<Storage>::has_emboss_reserved_anonymous_field_1() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericComplexView<Storage>::has_a0() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericComplexView<Storage>::has_s0() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericComplexView<Storage>::has_l0() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericComplexView<Storage>::has_h0() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+template <class Storage>
+inline typename ::emboss_test::GenericArrayElementView<typename Storage::template OffsetStorageType</**/0, 2>>
+
+ GenericComplexView<Storage>::e1()
+    const {
+
+  if ( has_e1().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss_test::GenericArrayElementView<typename Storage::template OffsetStorageType</**/0, 2>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss_test::GenericArrayElementView<typename Storage::template OffsetStorageType</**/0, 2>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericComplexView<Storage>::has_e1() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss_test::GenericArrayElementView<typename Storage::template OffsetStorageType</**/0, 3>>
+
+ GenericComplexView<Storage>::e2()
+    const {
+
+  if ( has_e2().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss_test::GenericArrayElementView<typename Storage::template OffsetStorageType</**/0, 3>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   3>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss_test::GenericArrayElementView<typename Storage::template OffsetStorageType</**/0, 3>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericComplexView<Storage>::has_e2() const {
+  return ::emboss::support::GreaterThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((a0().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(a0().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(128LL)));
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 8>>
+
+ GenericComplexView<Storage>::b2()
+    const {
+
+  if ( has_b2().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   3>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::BcdView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericComplexView<Storage>::has_b2() const {
+  return ::emboss::support::LessThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((a0().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(a0().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(128LL)));
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 8>>
+
+ GenericComplexView<Storage>::e3()
+    const {
+
+  if ( has_e3().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   4>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericComplexView<Storage>::has_e3() const {
+  return ::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((b2().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(b2().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(25LL)));
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 5>>, 8>>
+
+ GenericComplexView<Storage>::e4()
+    const {
+
+  if ( has_e4().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 5>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   5>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 5>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericComplexView<Storage>::has_e4() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::GreaterThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((s().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(s().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL))), ::emboss::support::Choice</**/bool, bool, bool, bool, bool>(::emboss::support::GreaterThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((a0().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(a0().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(80LL))), ::emboss::support::GreaterThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((e3().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(e3().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(128LL))), ::emboss::support::LessThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((b2().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(b2().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(50LL)))));
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 8>>
+
+ GenericComplexView<Storage>::e5()
+    const {
+
+  if ( has_e5().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   6>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericComplexView<Storage>::has_e5() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::GreaterThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((s().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(s().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL))), ::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((e4().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(e4().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL))));
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericComplexView<Storage>::e0()
+    const {
+
+  if ( has_e0().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericComplexView<Storage>::has_e0() const {
+  return ::emboss::support::Or</**/bool, bool, bool, bool>(::emboss::support::LessThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((s().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(s().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL))), ::emboss::support::LessThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((a0().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(a0().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL))));
+}
+
+
+template <class Storage>
+inline typename GenericComplexView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericComplexView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericComplexView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericComplexView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Complex {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1021LL)).ValueOrDefault();
+}
+}  // namespace Complex
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericComplexView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Complex::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericComplexView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Complex::MaxSizeInBytes();
+}
+
+namespace Complex {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(9LL)).ValueOrDefault();
+}
+}  // namespace Complex
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericComplexView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Complex::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericComplexView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Complex::MinSizeInBytes();
+}
+
+
+
+}  // namespace emboss_test
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_COMPLEX_STRUCTURE_EMB_H_
+
diff --git a/testdata/golden_cpp/condition.emb.h b/testdata/golden_cpp/condition.emb.h
new file mode 100644
index 0000000..9d11fb7
--- /dev/null
+++ b/testdata/golden_cpp/condition.emb.h
@@ -0,0 +1,24727 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_CONDITION_EMB_H_
+#define TESTDATA_CONDITION_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace BasicConditional {
+
+}  // namespace BasicConditional
+
+
+template <class Storage>
+class GenericBasicConditionalView;
+
+namespace NegativeConditional {
+
+}  // namespace NegativeConditional
+
+
+template <class Storage>
+class GenericNegativeConditionalView;
+
+namespace ConditionalAndUnconditionalOverlappingFinalField {
+
+}  // namespace ConditionalAndUnconditionalOverlappingFinalField
+
+
+template <class Storage>
+class GenericConditionalAndUnconditionalOverlappingFinalFieldView;
+
+namespace ConditionalBasicConditionalFieldFirst {
+
+}  // namespace ConditionalBasicConditionalFieldFirst
+
+
+template <class Storage>
+class GenericConditionalBasicConditionalFieldFirstView;
+
+namespace ConditionalAndDynamicLocation {
+
+}  // namespace ConditionalAndDynamicLocation
+
+
+template <class Storage>
+class GenericConditionalAndDynamicLocationView;
+
+namespace ConditionUsesMinInt {
+
+}  // namespace ConditionUsesMinInt
+
+
+template <class Storage>
+class GenericConditionUsesMinIntView;
+
+namespace NestedConditional {
+
+}  // namespace NestedConditional
+
+
+template <class Storage>
+class GenericNestedConditionalView;
+
+namespace CorrectNestedConditional {
+
+}  // namespace CorrectNestedConditional
+
+
+template <class Storage>
+class GenericCorrectNestedConditionalView;
+
+namespace AlwaysFalseCondition {
+
+}  // namespace AlwaysFalseCondition
+
+
+template <class Storage>
+class GenericAlwaysFalseConditionView;
+
+namespace OnlyAlwaysFalseCondition {
+
+}  // namespace OnlyAlwaysFalseCondition
+
+
+template <class Storage>
+class GenericOnlyAlwaysFalseConditionView;
+
+namespace EmptyStruct {
+
+}  // namespace EmptyStruct
+
+
+template <class Storage>
+class GenericEmptyStructView;
+
+namespace AlwaysFalseConditionDynamicSize {
+
+}  // namespace AlwaysFalseConditionDynamicSize
+
+
+template <class Storage>
+class GenericAlwaysFalseConditionDynamicSizeView;
+
+namespace ConditionDoesNotContributeToSize {
+
+}  // namespace ConditionDoesNotContributeToSize
+
+
+template <class Storage>
+class GenericConditionDoesNotContributeToSizeView;
+
+enum class OnOff : ::std::uint64_t;
+
+namespace EnumCondition {
+
+}  // namespace EnumCondition
+
+
+template <class Storage>
+class GenericEnumConditionView;
+
+namespace NegativeEnumCondition {
+
+}  // namespace NegativeEnumCondition
+
+
+template <class Storage>
+class GenericNegativeEnumConditionView;
+
+namespace LessThanCondition {
+
+}  // namespace LessThanCondition
+
+
+template <class Storage>
+class GenericLessThanConditionView;
+
+namespace LessThanOrEqualCondition {
+
+}  // namespace LessThanOrEqualCondition
+
+
+template <class Storage>
+class GenericLessThanOrEqualConditionView;
+
+namespace GreaterThanOrEqualCondition {
+
+}  // namespace GreaterThanOrEqualCondition
+
+
+template <class Storage>
+class GenericGreaterThanOrEqualConditionView;
+
+namespace GreaterThanCondition {
+
+}  // namespace GreaterThanCondition
+
+
+template <class Storage>
+class GenericGreaterThanConditionView;
+
+namespace RangeCondition {
+
+}  // namespace RangeCondition
+
+
+template <class Storage>
+class GenericRangeConditionView;
+
+namespace ReverseRangeCondition {
+
+}  // namespace ReverseRangeCondition
+
+
+template <class Storage>
+class GenericReverseRangeConditionView;
+
+namespace AndCondition {
+
+}  // namespace AndCondition
+
+
+template <class Storage>
+class GenericAndConditionView;
+
+namespace OrCondition {
+
+}  // namespace OrCondition
+
+
+template <class Storage>
+class GenericOrConditionView;
+
+namespace ChoiceCondition {
+enum class Field : ::std::uint64_t;
+
+
+}  // namespace ChoiceCondition
+
+
+template <class Storage>
+class GenericChoiceConditionView;
+
+namespace ContainsBits {
+namespace EmbossReservedAnonymousField3 {
+
+}  // namespace EmbossReservedAnonymousField3
+
+
+template <class Storage>
+class GenericEmbossReservedAnonymousField3View;
+
+
+}  // namespace ContainsBits
+
+
+template <class Storage>
+class GenericContainsBitsView;
+
+namespace ContainsContainsBits {
+
+}  // namespace ContainsContainsBits
+
+
+template <class Storage>
+class GenericContainsContainsBitsView;
+
+namespace ConditionalInline {
+namespace Type0 {
+
+}  // namespace Type0
+
+
+template <class Storage>
+class GenericType0View;
+
+
+namespace Type1 {
+
+}  // namespace Type1
+
+
+template <class Storage>
+class GenericType1View;
+
+
+}  // namespace ConditionalInline
+
+
+template <class Storage>
+class GenericConditionalInlineView;
+
+namespace ConditionalAnonymous {
+namespace EmbossReservedAnonymousField2 {
+
+}  // namespace EmbossReservedAnonymousField2
+
+
+template <class Storage>
+class GenericEmbossReservedAnonymousField2View;
+
+
+}  // namespace ConditionalAnonymous
+
+
+template <class Storage>
+class GenericConditionalAnonymousView;
+
+namespace ConditionalOnFlag {
+namespace EmbossReservedAnonymousField1 {
+
+}  // namespace EmbossReservedAnonymousField1
+
+
+template <class Storage>
+class GenericEmbossReservedAnonymousField1View;
+
+
+}  // namespace ConditionalOnFlag
+
+
+template <class Storage>
+class GenericConditionalOnFlagView;
+
+
+
+
+
+
+namespace BasicConditional {
+
+}  // namespace BasicConditional
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericBasicConditionalView;
+
+template <class Storage>
+class GenericBasicConditionalView final {
+ public:
+  GenericBasicConditionalView() : backing_() {}
+  explicit GenericBasicConditionalView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericBasicConditionalView(
+      const GenericBasicConditionalView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericBasicConditionalView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericBasicConditionalView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericBasicConditionalView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericBasicConditionalView<Storage> &operator=(
+      const GenericBasicConditionalView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_xc().Known()) return false;
+    if (has_xc().ValueOrDefault() && !xc().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericBasicConditionalView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_xc().Known()) return false;
+    if (!emboss_reserved_local_other.has_xc().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        !has_xc().ValueOrDefault())
+      return false;
+    if (has_xc().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xc().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        has_xc().ValueOrDefault() &&
+        !xc().Equals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericBasicConditionalView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        !has_xc().ValueOr(false))
+      return false;
+    if (has_xc().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xc().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        has_xc().ValueOr(false) &&
+        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericBasicConditionalView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericBasicConditionalView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericBasicConditionalView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "xc") {
+        if (!xc().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_xc().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xc().IsAggregate() || xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xc: ");
+        xc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xc().IsAggregate() && !xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xc: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ xc() const;
+  ::emboss::support::Maybe<bool> has_xc() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericBasicConditionalView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_4);
+
+      return emboss_reserved_local_subexpr_5;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericBasicConditionalView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericBasicConditionalView;
+};
+using BasicConditionalView =
+    GenericBasicConditionalView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using BasicConditionalWriter =
+    GenericBasicConditionalView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericBasicConditionalView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericBasicConditionalView<
+    GenericBasicConditionalView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericBasicConditionalView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeBasicConditionalView( T &&emboss_reserved_local_arg) {
+  return GenericBasicConditionalView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericBasicConditionalView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeBasicConditionalView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericBasicConditionalView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericBasicConditionalView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedBasicConditionalView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericBasicConditionalView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace NegativeConditional {
+
+}  // namespace NegativeConditional
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericNegativeConditionalView;
+
+template <class Storage>
+class GenericNegativeConditionalView final {
+ public:
+  GenericNegativeConditionalView() : backing_() {}
+  explicit GenericNegativeConditionalView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericNegativeConditionalView(
+      const GenericNegativeConditionalView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericNegativeConditionalView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericNegativeConditionalView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericNegativeConditionalView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericNegativeConditionalView<Storage> &operator=(
+      const GenericNegativeConditionalView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_xc().Known()) return false;
+    if (has_xc().ValueOrDefault() && !xc().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericNegativeConditionalView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_xc().Known()) return false;
+    if (!emboss_reserved_local_other.has_xc().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        !has_xc().ValueOrDefault())
+      return false;
+    if (has_xc().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xc().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        has_xc().ValueOrDefault() &&
+        !xc().Equals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericNegativeConditionalView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        !has_xc().ValueOr(false))
+      return false;
+    if (has_xc().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xc().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        has_xc().ValueOr(false) &&
+        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericNegativeConditionalView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericNegativeConditionalView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericNegativeConditionalView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "xc") {
+        if (!xc().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_xc().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xc().IsAggregate() || xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xc: ");
+        xc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xc().IsAggregate() && !xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xc: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ xc() const;
+  ::emboss::support::Maybe<bool> has_xc() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericNegativeConditionalView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::NotEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_4);
+
+      return emboss_reserved_local_subexpr_5;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericNegativeConditionalView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericNegativeConditionalView;
+};
+using NegativeConditionalView =
+    GenericNegativeConditionalView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using NegativeConditionalWriter =
+    GenericNegativeConditionalView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericNegativeConditionalView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericNegativeConditionalView<
+    GenericNegativeConditionalView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericNegativeConditionalView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeNegativeConditionalView( T &&emboss_reserved_local_arg) {
+  return GenericNegativeConditionalView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericNegativeConditionalView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeNegativeConditionalView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericNegativeConditionalView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericNegativeConditionalView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedNegativeConditionalView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericNegativeConditionalView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace ConditionalAndUnconditionalOverlappingFinalField {
+
+}  // namespace ConditionalAndUnconditionalOverlappingFinalField
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericConditionalAndUnconditionalOverlappingFinalFieldView;
+
+template <class Storage>
+class GenericConditionalAndUnconditionalOverlappingFinalFieldView final {
+ public:
+  GenericConditionalAndUnconditionalOverlappingFinalFieldView() : backing_() {}
+  explicit GenericConditionalAndUnconditionalOverlappingFinalFieldView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericConditionalAndUnconditionalOverlappingFinalFieldView(
+      const GenericConditionalAndUnconditionalOverlappingFinalFieldView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericConditionalAndUnconditionalOverlappingFinalFieldView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericConditionalAndUnconditionalOverlappingFinalFieldView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericConditionalAndUnconditionalOverlappingFinalFieldView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericConditionalAndUnconditionalOverlappingFinalFieldView<Storage> &operator=(
+      const GenericConditionalAndUnconditionalOverlappingFinalFieldView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_xc().Known()) return false;
+    if (has_xc().ValueOrDefault() && !xc().Ok()) return false;
+
+
+    if (!has_z().Known()) return false;
+    if (has_z().ValueOrDefault() && !z().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericConditionalAndUnconditionalOverlappingFinalFieldView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_xc().Known()) return false;
+    if (!emboss_reserved_local_other.has_xc().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        !has_xc().ValueOrDefault())
+      return false;
+    if (has_xc().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xc().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        has_xc().ValueOrDefault() &&
+        !xc().Equals(emboss_reserved_local_other.xc()))
+      return false;
+
+
+
+    if (!has_z().Known()) return false;
+    if (!emboss_reserved_local_other.has_z().Known()) return false;
+
+    if (emboss_reserved_local_other.has_z().ValueOrDefault() &&
+        !has_z().ValueOrDefault())
+      return false;
+    if (has_z().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_z().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_z().ValueOrDefault() &&
+        has_z().ValueOrDefault() &&
+        !z().Equals(emboss_reserved_local_other.z()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericConditionalAndUnconditionalOverlappingFinalFieldView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        !has_xc().ValueOr(false))
+      return false;
+    if (has_xc().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xc().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        has_xc().ValueOr(false) &&
+        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_z().ValueOr(false) &&
+        !has_z().ValueOr(false))
+      return false;
+    if (has_z().ValueOr(false) &&
+        !emboss_reserved_local_other.has_z().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_z().ValueOr(false) &&
+        has_z().ValueOr(false) &&
+        !z().UncheckedEquals(emboss_reserved_local_other.z()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericConditionalAndUnconditionalOverlappingFinalFieldView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericConditionalAndUnconditionalOverlappingFinalFieldView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericConditionalAndUnconditionalOverlappingFinalFieldView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "xc") {
+        if (!xc().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "z") {
+        if (!z().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_xc().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xc().IsAggregate() || xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xc: ");
+        xc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xc().IsAggregate() && !xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xc: UNREADABLE\n");
+      }
+    }
+
+    if (has_z().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          z().IsAggregate() || z().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("z: ");
+        z().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !z().IsAggregate() && !z().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# z: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ xc() const;
+  ::emboss::support::Maybe<bool> has_xc() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ z() const;
+  ::emboss::support::Maybe<bool> has_z() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericConditionalAndUnconditionalOverlappingFinalFieldView;
+};
+using ConditionalAndUnconditionalOverlappingFinalFieldView =
+    GenericConditionalAndUnconditionalOverlappingFinalFieldView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ConditionalAndUnconditionalOverlappingFinalFieldWriter =
+    GenericConditionalAndUnconditionalOverlappingFinalFieldView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericConditionalAndUnconditionalOverlappingFinalFieldView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericConditionalAndUnconditionalOverlappingFinalFieldView<
+    GenericConditionalAndUnconditionalOverlappingFinalFieldView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericConditionalAndUnconditionalOverlappingFinalFieldView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeConditionalAndUnconditionalOverlappingFinalFieldView( T &&emboss_reserved_local_arg) {
+  return GenericConditionalAndUnconditionalOverlappingFinalFieldView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericConditionalAndUnconditionalOverlappingFinalFieldView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeConditionalAndUnconditionalOverlappingFinalFieldView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericConditionalAndUnconditionalOverlappingFinalFieldView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericConditionalAndUnconditionalOverlappingFinalFieldView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedConditionalAndUnconditionalOverlappingFinalFieldView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericConditionalAndUnconditionalOverlappingFinalFieldView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace ConditionalBasicConditionalFieldFirst {
+
+}  // namespace ConditionalBasicConditionalFieldFirst
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericConditionalBasicConditionalFieldFirstView;
+
+template <class Storage>
+class GenericConditionalBasicConditionalFieldFirstView final {
+ public:
+  GenericConditionalBasicConditionalFieldFirstView() : backing_() {}
+  explicit GenericConditionalBasicConditionalFieldFirstView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericConditionalBasicConditionalFieldFirstView(
+      const GenericConditionalBasicConditionalFieldFirstView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericConditionalBasicConditionalFieldFirstView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericConditionalBasicConditionalFieldFirstView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericConditionalBasicConditionalFieldFirstView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericConditionalBasicConditionalFieldFirstView<Storage> &operator=(
+      const GenericConditionalBasicConditionalFieldFirstView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_xc().Known()) return false;
+    if (has_xc().ValueOrDefault() && !xc().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericConditionalBasicConditionalFieldFirstView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_xc().Known()) return false;
+    if (!emboss_reserved_local_other.has_xc().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        !has_xc().ValueOrDefault())
+      return false;
+    if (has_xc().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xc().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        has_xc().ValueOrDefault() &&
+        !xc().Equals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericConditionalBasicConditionalFieldFirstView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        !has_xc().ValueOr(false))
+      return false;
+    if (has_xc().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xc().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        has_xc().ValueOr(false) &&
+        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericConditionalBasicConditionalFieldFirstView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericConditionalBasicConditionalFieldFirstView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericConditionalBasicConditionalFieldFirstView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "xc") {
+        if (!xc().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_xc().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xc().IsAggregate() || xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xc: ");
+        xc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xc().IsAggregate() && !xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xc: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ xc() const;
+  ::emboss::support::Maybe<bool> has_xc() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericConditionalBasicConditionalFieldFirstView;
+};
+using ConditionalBasicConditionalFieldFirstView =
+    GenericConditionalBasicConditionalFieldFirstView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ConditionalBasicConditionalFieldFirstWriter =
+    GenericConditionalBasicConditionalFieldFirstView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericConditionalBasicConditionalFieldFirstView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericConditionalBasicConditionalFieldFirstView<
+    GenericConditionalBasicConditionalFieldFirstView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericConditionalBasicConditionalFieldFirstView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeConditionalBasicConditionalFieldFirstView( T &&emboss_reserved_local_arg) {
+  return GenericConditionalBasicConditionalFieldFirstView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericConditionalBasicConditionalFieldFirstView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeConditionalBasicConditionalFieldFirstView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericConditionalBasicConditionalFieldFirstView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericConditionalBasicConditionalFieldFirstView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedConditionalBasicConditionalFieldFirstView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericConditionalBasicConditionalFieldFirstView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace ConditionalAndDynamicLocation {
+
+}  // namespace ConditionalAndDynamicLocation
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericConditionalAndDynamicLocationView;
+
+template <class Storage>
+class GenericConditionalAndDynamicLocationView final {
+ public:
+  GenericConditionalAndDynamicLocationView() : backing_() {}
+  explicit GenericConditionalAndDynamicLocationView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericConditionalAndDynamicLocationView(
+      const GenericConditionalAndDynamicLocationView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericConditionalAndDynamicLocationView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericConditionalAndDynamicLocationView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericConditionalAndDynamicLocationView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericConditionalAndDynamicLocationView<Storage> &operator=(
+      const GenericConditionalAndDynamicLocationView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_y().Known()) return false;
+    if (has_y().ValueOrDefault() && !y().Ok()) return false;
+
+
+    if (!has_xc().Known()) return false;
+    if (has_xc().ValueOrDefault() && !xc().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericConditionalAndDynamicLocationView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_y().Known()) return false;
+    if (!emboss_reserved_local_other.has_y().Known()) return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
+        !has_y().ValueOrDefault())
+      return false;
+    if (has_y().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_y().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
+        has_y().ValueOrDefault() &&
+        !y().Equals(emboss_reserved_local_other.y()))
+      return false;
+
+
+
+    if (!has_xc().Known()) return false;
+    if (!emboss_reserved_local_other.has_xc().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        !has_xc().ValueOrDefault())
+      return false;
+    if (has_xc().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xc().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        has_xc().ValueOrDefault() &&
+        !xc().Equals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericConditionalAndDynamicLocationView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
+        !has_y().ValueOr(false))
+      return false;
+    if (has_y().ValueOr(false) &&
+        !emboss_reserved_local_other.has_y().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
+        has_y().ValueOr(false) &&
+        !y().UncheckedEquals(emboss_reserved_local_other.y()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        !has_xc().ValueOr(false))
+      return false;
+    if (has_xc().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xc().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        has_xc().ValueOr(false) &&
+        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericConditionalAndDynamicLocationView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericConditionalAndDynamicLocationView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericConditionalAndDynamicLocationView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "y") {
+        if (!y().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "xc") {
+        if (!xc().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_y().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          y().IsAggregate() || y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("y: ");
+        y().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !y().IsAggregate() && !y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# y: UNREADABLE\n");
+      }
+    }
+
+    if (has_xc().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xc().IsAggregate() || xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xc: ");
+        xc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xc().IsAggregate() && !xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xc: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ y() const;
+  ::emboss::support::Maybe<bool> has_y() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+ xc() const;
+  ::emboss::support::Maybe<bool> has_xc() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericConditionalAndDynamicLocationView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_4 = view_.y();
+      const auto emboss_reserved_local_subexpr_5 = (emboss_reserved_local_subexpr_4.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_4.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_5, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, emboss_reserved_local_subexpr_6, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_8 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)), emboss_reserved_local_subexpr_7);
+
+      return emboss_reserved_local_subexpr_8;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericConditionalAndDynamicLocationView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericConditionalAndDynamicLocationView;
+};
+using ConditionalAndDynamicLocationView =
+    GenericConditionalAndDynamicLocationView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ConditionalAndDynamicLocationWriter =
+    GenericConditionalAndDynamicLocationView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericConditionalAndDynamicLocationView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericConditionalAndDynamicLocationView<
+    GenericConditionalAndDynamicLocationView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericConditionalAndDynamicLocationView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeConditionalAndDynamicLocationView( T &&emboss_reserved_local_arg) {
+  return GenericConditionalAndDynamicLocationView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericConditionalAndDynamicLocationView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeConditionalAndDynamicLocationView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericConditionalAndDynamicLocationView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericConditionalAndDynamicLocationView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedConditionalAndDynamicLocationView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericConditionalAndDynamicLocationView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace ConditionUsesMinInt {
+
+}  // namespace ConditionUsesMinInt
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericConditionUsesMinIntView;
+
+template <class Storage>
+class GenericConditionUsesMinIntView final {
+ public:
+  GenericConditionUsesMinIntView() : backing_() {}
+  explicit GenericConditionUsesMinIntView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericConditionUsesMinIntView(
+      const GenericConditionUsesMinIntView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericConditionUsesMinIntView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericConditionUsesMinIntView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericConditionUsesMinIntView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericConditionUsesMinIntView<Storage> &operator=(
+      const GenericConditionUsesMinIntView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_xc().Known()) return false;
+    if (has_xc().ValueOrDefault() && !xc().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericConditionUsesMinIntView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_xc().Known()) return false;
+    if (!emboss_reserved_local_other.has_xc().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        !has_xc().ValueOrDefault())
+      return false;
+    if (has_xc().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xc().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        has_xc().ValueOrDefault() &&
+        !xc().Equals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericConditionUsesMinIntView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        !has_xc().ValueOr(false))
+      return false;
+    if (has_xc().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xc().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        has_xc().ValueOr(false) &&
+        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericConditionUsesMinIntView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericConditionUsesMinIntView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericConditionUsesMinIntView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "xc") {
+        if (!xc().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_xc().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xc().IsAggregate() || xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xc: ");
+        xc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xc().IsAggregate() && !xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xc: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ xc() const;
+  ::emboss::support::Maybe<bool> has_xc() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericConditionUsesMinIntView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Difference</**/::std::int64_t, ::std::int64_t, ::std::int32_t, ::std::int64_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int64_t>(static_cast</**/::std::int64_t>(9223372036854775680LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Equal</**/::std::int64_t, bool, ::std::int64_t, ::std::int64_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int64_t>(static_cast</**/::std::int64_t>(-9223372036854775807LL - 1)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_4, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_5);
+
+      return emboss_reserved_local_subexpr_6;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericConditionUsesMinIntView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericConditionUsesMinIntView;
+};
+using ConditionUsesMinIntView =
+    GenericConditionUsesMinIntView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ConditionUsesMinIntWriter =
+    GenericConditionUsesMinIntView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericConditionUsesMinIntView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericConditionUsesMinIntView<
+    GenericConditionUsesMinIntView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericConditionUsesMinIntView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeConditionUsesMinIntView( T &&emboss_reserved_local_arg) {
+  return GenericConditionUsesMinIntView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericConditionUsesMinIntView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeConditionUsesMinIntView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericConditionUsesMinIntView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericConditionUsesMinIntView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedConditionUsesMinIntView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericConditionUsesMinIntView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace NestedConditional {
+
+}  // namespace NestedConditional
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericNestedConditionalView;
+
+template <class Storage>
+class GenericNestedConditionalView final {
+ public:
+  GenericNestedConditionalView() : backing_() {}
+  explicit GenericNestedConditionalView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericNestedConditionalView(
+      const GenericNestedConditionalView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericNestedConditionalView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericNestedConditionalView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericNestedConditionalView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericNestedConditionalView<Storage> &operator=(
+      const GenericNestedConditionalView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_xc().Known()) return false;
+    if (has_xc().ValueOrDefault() && !xc().Ok()) return false;
+
+
+    if (!has_xcc().Known()) return false;
+    if (has_xcc().ValueOrDefault() && !xcc().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericNestedConditionalView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_xc().Known()) return false;
+    if (!emboss_reserved_local_other.has_xc().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        !has_xc().ValueOrDefault())
+      return false;
+    if (has_xc().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xc().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        has_xc().ValueOrDefault() &&
+        !xc().Equals(emboss_reserved_local_other.xc()))
+      return false;
+
+
+
+    if (!has_xcc().Known()) return false;
+    if (!emboss_reserved_local_other.has_xcc().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xcc().ValueOrDefault() &&
+        !has_xcc().ValueOrDefault())
+      return false;
+    if (has_xcc().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xcc().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xcc().ValueOrDefault() &&
+        has_xcc().ValueOrDefault() &&
+        !xcc().Equals(emboss_reserved_local_other.xcc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericNestedConditionalView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        !has_xc().ValueOr(false))
+      return false;
+    if (has_xc().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xc().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        has_xc().ValueOr(false) &&
+        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_xcc().ValueOr(false) &&
+        !has_xcc().ValueOr(false))
+      return false;
+    if (has_xcc().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xcc().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xcc().ValueOr(false) &&
+        has_xcc().ValueOr(false) &&
+        !xcc().UncheckedEquals(emboss_reserved_local_other.xcc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericNestedConditionalView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericNestedConditionalView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericNestedConditionalView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "xc") {
+        if (!xc().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "xcc") {
+        if (!xcc().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_xc().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xc().IsAggregate() || xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xc: ");
+        xc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xc().IsAggregate() && !xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xc: UNREADABLE\n");
+      }
+    }
+
+    if (has_xcc().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xcc().IsAggregate() || xcc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xcc: ");
+        xcc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xcc().IsAggregate() && !xcc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xcc: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ xc() const;
+  ::emboss::support::Maybe<bool> has_xc() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ xcc() const;
+  ::emboss::support::Maybe<bool> has_xcc() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericNestedConditionalView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = view_.xc();
+      const auto emboss_reserved_local_subexpr_6 = (emboss_reserved_local_subexpr_5.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_5.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_6, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_8 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_7, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_9 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_4, emboss_reserved_local_subexpr_8);
+
+      return emboss_reserved_local_subexpr_9;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericNestedConditionalView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericNestedConditionalView;
+};
+using NestedConditionalView =
+    GenericNestedConditionalView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using NestedConditionalWriter =
+    GenericNestedConditionalView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericNestedConditionalView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericNestedConditionalView<
+    GenericNestedConditionalView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericNestedConditionalView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeNestedConditionalView( T &&emboss_reserved_local_arg) {
+  return GenericNestedConditionalView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericNestedConditionalView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeNestedConditionalView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericNestedConditionalView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericNestedConditionalView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedNestedConditionalView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericNestedConditionalView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace CorrectNestedConditional {
+
+}  // namespace CorrectNestedConditional
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericCorrectNestedConditionalView;
+
+template <class Storage>
+class GenericCorrectNestedConditionalView final {
+ public:
+  GenericCorrectNestedConditionalView() : backing_() {}
+  explicit GenericCorrectNestedConditionalView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericCorrectNestedConditionalView(
+      const GenericCorrectNestedConditionalView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericCorrectNestedConditionalView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericCorrectNestedConditionalView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericCorrectNestedConditionalView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericCorrectNestedConditionalView<Storage> &operator=(
+      const GenericCorrectNestedConditionalView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_xc().Known()) return false;
+    if (has_xc().ValueOrDefault() && !xc().Ok()) return false;
+
+
+    if (!has_xcc().Known()) return false;
+    if (has_xcc().ValueOrDefault() && !xcc().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericCorrectNestedConditionalView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_xc().Known()) return false;
+    if (!emboss_reserved_local_other.has_xc().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        !has_xc().ValueOrDefault())
+      return false;
+    if (has_xc().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xc().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        has_xc().ValueOrDefault() &&
+        !xc().Equals(emboss_reserved_local_other.xc()))
+      return false;
+
+
+
+    if (!has_xcc().Known()) return false;
+    if (!emboss_reserved_local_other.has_xcc().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xcc().ValueOrDefault() &&
+        !has_xcc().ValueOrDefault())
+      return false;
+    if (has_xcc().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xcc().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xcc().ValueOrDefault() &&
+        has_xcc().ValueOrDefault() &&
+        !xcc().Equals(emboss_reserved_local_other.xcc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericCorrectNestedConditionalView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        !has_xc().ValueOr(false))
+      return false;
+    if (has_xc().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xc().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        has_xc().ValueOr(false) &&
+        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_xcc().ValueOr(false) &&
+        !has_xcc().ValueOr(false))
+      return false;
+    if (has_xcc().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xcc().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xcc().ValueOr(false) &&
+        has_xcc().ValueOr(false) &&
+        !xcc().UncheckedEquals(emboss_reserved_local_other.xcc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericCorrectNestedConditionalView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericCorrectNestedConditionalView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericCorrectNestedConditionalView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "xc") {
+        if (!xc().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "xcc") {
+        if (!xcc().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_xc().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xc().IsAggregate() || xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xc: ");
+        xc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xc().IsAggregate() && !xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xc: UNREADABLE\n");
+      }
+    }
+
+    if (has_xcc().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xcc().IsAggregate() || xcc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xcc: ");
+        xcc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xcc().IsAggregate() && !xcc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xcc: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ xc() const;
+  ::emboss::support::Maybe<bool> has_xc() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ xcc() const;
+  ::emboss::support::Maybe<bool> has_xcc() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericCorrectNestedConditionalView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = view_.xc();
+      const auto emboss_reserved_local_subexpr_6 = (emboss_reserved_local_subexpr_5.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_5.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_6, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_8 = ::emboss::support::And</**/bool, bool, bool, bool>(emboss_reserved_local_subexpr_3, emboss_reserved_local_subexpr_7);
+      const auto emboss_reserved_local_subexpr_9 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_8, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_10 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_4, emboss_reserved_local_subexpr_9);
+
+      return emboss_reserved_local_subexpr_10;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericCorrectNestedConditionalView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericCorrectNestedConditionalView;
+};
+using CorrectNestedConditionalView =
+    GenericCorrectNestedConditionalView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using CorrectNestedConditionalWriter =
+    GenericCorrectNestedConditionalView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericCorrectNestedConditionalView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericCorrectNestedConditionalView<
+    GenericCorrectNestedConditionalView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericCorrectNestedConditionalView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeCorrectNestedConditionalView( T &&emboss_reserved_local_arg) {
+  return GenericCorrectNestedConditionalView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericCorrectNestedConditionalView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeCorrectNestedConditionalView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericCorrectNestedConditionalView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericCorrectNestedConditionalView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedCorrectNestedConditionalView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericCorrectNestedConditionalView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace AlwaysFalseCondition {
+
+}  // namespace AlwaysFalseCondition
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericAlwaysFalseConditionView;
+
+template <class Storage>
+class GenericAlwaysFalseConditionView final {
+ public:
+  GenericAlwaysFalseConditionView() : backing_() {}
+  explicit GenericAlwaysFalseConditionView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericAlwaysFalseConditionView(
+      const GenericAlwaysFalseConditionView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericAlwaysFalseConditionView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericAlwaysFalseConditionView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericAlwaysFalseConditionView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericAlwaysFalseConditionView<Storage> &operator=(
+      const GenericAlwaysFalseConditionView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_xc().Known()) return false;
+    if (has_xc().ValueOrDefault() && !xc().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericAlwaysFalseConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_xc().Known()) return false;
+    if (!emboss_reserved_local_other.has_xc().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        !has_xc().ValueOrDefault())
+      return false;
+    if (has_xc().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xc().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        has_xc().ValueOrDefault() &&
+        !xc().Equals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericAlwaysFalseConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        !has_xc().ValueOr(false))
+      return false;
+    if (has_xc().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xc().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        has_xc().ValueOr(false) &&
+        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericAlwaysFalseConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericAlwaysFalseConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericAlwaysFalseConditionView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "xc") {
+        if (!xc().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_xc().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xc().IsAggregate() || xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xc: ");
+        xc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xc().IsAggregate() && !xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xc: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ xc() const;
+  ::emboss::support::Maybe<bool> has_xc() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericAlwaysFalseConditionView;
+};
+using AlwaysFalseConditionView =
+    GenericAlwaysFalseConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using AlwaysFalseConditionWriter =
+    GenericAlwaysFalseConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericAlwaysFalseConditionView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericAlwaysFalseConditionView<
+    GenericAlwaysFalseConditionView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericAlwaysFalseConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeAlwaysFalseConditionView( T &&emboss_reserved_local_arg) {
+  return GenericAlwaysFalseConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericAlwaysFalseConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeAlwaysFalseConditionView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericAlwaysFalseConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericAlwaysFalseConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedAlwaysFalseConditionView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericAlwaysFalseConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+namespace OnlyAlwaysFalseCondition {
+
+}  // namespace OnlyAlwaysFalseCondition
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericOnlyAlwaysFalseConditionView;
+
+template <class Storage>
+class GenericOnlyAlwaysFalseConditionView final {
+ public:
+  GenericOnlyAlwaysFalseConditionView() : backing_() {}
+  explicit GenericOnlyAlwaysFalseConditionView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericOnlyAlwaysFalseConditionView(
+      const GenericOnlyAlwaysFalseConditionView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericOnlyAlwaysFalseConditionView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericOnlyAlwaysFalseConditionView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericOnlyAlwaysFalseConditionView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericOnlyAlwaysFalseConditionView<Storage> &operator=(
+      const GenericOnlyAlwaysFalseConditionView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_xc().Known()) return false;
+    if (has_xc().ValueOrDefault() && !xc().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericOnlyAlwaysFalseConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_xc().Known()) return false;
+    if (!emboss_reserved_local_other.has_xc().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        !has_xc().ValueOrDefault())
+      return false;
+    if (has_xc().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xc().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        has_xc().ValueOrDefault() &&
+        !xc().Equals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericOnlyAlwaysFalseConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        !has_xc().ValueOr(false))
+      return false;
+    if (has_xc().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xc().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        has_xc().ValueOr(false) &&
+        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericOnlyAlwaysFalseConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericOnlyAlwaysFalseConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericOnlyAlwaysFalseConditionView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "xc") {
+        if (!xc().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_xc().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xc().IsAggregate() || xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xc: ");
+        xc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xc().IsAggregate() && !xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xc: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ xc() const;
+  ::emboss::support::Maybe<bool> has_xc() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericOnlyAlwaysFalseConditionView;
+};
+using OnlyAlwaysFalseConditionView =
+    GenericOnlyAlwaysFalseConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using OnlyAlwaysFalseConditionWriter =
+    GenericOnlyAlwaysFalseConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericOnlyAlwaysFalseConditionView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericOnlyAlwaysFalseConditionView<
+    GenericOnlyAlwaysFalseConditionView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericOnlyAlwaysFalseConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeOnlyAlwaysFalseConditionView( T &&emboss_reserved_local_arg) {
+  return GenericOnlyAlwaysFalseConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericOnlyAlwaysFalseConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeOnlyAlwaysFalseConditionView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericOnlyAlwaysFalseConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericOnlyAlwaysFalseConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedOnlyAlwaysFalseConditionView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericOnlyAlwaysFalseConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+namespace EmptyStruct {
+
+}  // namespace EmptyStruct
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericEmptyStructView;
+
+template <class Storage>
+class GenericEmptyStructView final {
+ public:
+  GenericEmptyStructView() : backing_() {}
+  explicit GenericEmptyStructView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEmptyStructView(
+      const GenericEmptyStructView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericEmptyStructView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericEmptyStructView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericEmptyStructView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEmptyStructView<Storage> &operator=(
+      const GenericEmptyStructView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericEmptyStructView<OtherStorage> emboss_reserved_local_other) const {
+     return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericEmptyStructView<OtherStorage> emboss_reserved_local_other) const {
+     return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericEmptyStructView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericEmptyStructView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericEmptyStructView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericEmptyStructView;
+};
+using EmptyStructView =
+    GenericEmptyStructView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using EmptyStructWriter =
+    GenericEmptyStructView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericEmptyStructView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericEmptyStructView<
+    GenericEmptyStructView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericEmptyStructView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeEmptyStructView( T &&emboss_reserved_local_arg) {
+  return GenericEmptyStructView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericEmptyStructView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeEmptyStructView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericEmptyStructView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericEmptyStructView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedEmptyStructView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericEmptyStructView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace AlwaysFalseConditionDynamicSize {
+
+}  // namespace AlwaysFalseConditionDynamicSize
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericAlwaysFalseConditionDynamicSizeView;
+
+template <class Storage>
+class GenericAlwaysFalseConditionDynamicSizeView final {
+ public:
+  GenericAlwaysFalseConditionDynamicSizeView() : backing_() {}
+  explicit GenericAlwaysFalseConditionDynamicSizeView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericAlwaysFalseConditionDynamicSizeView(
+      const GenericAlwaysFalseConditionDynamicSizeView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericAlwaysFalseConditionDynamicSizeView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericAlwaysFalseConditionDynamicSizeView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericAlwaysFalseConditionDynamicSizeView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericAlwaysFalseConditionDynamicSizeView<Storage> &operator=(
+      const GenericAlwaysFalseConditionDynamicSizeView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_y().Known()) return false;
+    if (has_y().ValueOrDefault() && !y().Ok()) return false;
+
+
+    if (!has_xc().Known()) return false;
+    if (has_xc().ValueOrDefault() && !xc().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericAlwaysFalseConditionDynamicSizeView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_y().Known()) return false;
+    if (!emboss_reserved_local_other.has_y().Known()) return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
+        !has_y().ValueOrDefault())
+      return false;
+    if (has_y().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_y().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
+        has_y().ValueOrDefault() &&
+        !y().Equals(emboss_reserved_local_other.y()))
+      return false;
+
+
+
+    if (!has_xc().Known()) return false;
+    if (!emboss_reserved_local_other.has_xc().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        !has_xc().ValueOrDefault())
+      return false;
+    if (has_xc().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xc().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        has_xc().ValueOrDefault() &&
+        !xc().Equals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericAlwaysFalseConditionDynamicSizeView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
+        !has_y().ValueOr(false))
+      return false;
+    if (has_y().ValueOr(false) &&
+        !emboss_reserved_local_other.has_y().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
+        has_y().ValueOr(false) &&
+        !y().UncheckedEquals(emboss_reserved_local_other.y()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        !has_xc().ValueOr(false))
+      return false;
+    if (has_xc().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xc().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        has_xc().ValueOr(false) &&
+        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericAlwaysFalseConditionDynamicSizeView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericAlwaysFalseConditionDynamicSizeView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericAlwaysFalseConditionDynamicSizeView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "y") {
+        if (!y().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "xc") {
+        if (!xc().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_y().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          y().IsAggregate() || y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("y: ");
+        y().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !y().IsAggregate() && !y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# y: UNREADABLE\n");
+      }
+    }
+
+    if (has_xc().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xc().IsAggregate() || xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xc: ");
+        xc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xc().IsAggregate() && !xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xc: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+ y() const;
+  ::emboss::support::Maybe<bool> has_y() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ xc() const;
+  ::emboss::support::Maybe<bool> has_xc() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericAlwaysFalseConditionDynamicSizeView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_4, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+
+      return emboss_reserved_local_subexpr_5;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericAlwaysFalseConditionDynamicSizeView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericAlwaysFalseConditionDynamicSizeView;
+};
+using AlwaysFalseConditionDynamicSizeView =
+    GenericAlwaysFalseConditionDynamicSizeView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using AlwaysFalseConditionDynamicSizeWriter =
+    GenericAlwaysFalseConditionDynamicSizeView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericAlwaysFalseConditionDynamicSizeView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericAlwaysFalseConditionDynamicSizeView<
+    GenericAlwaysFalseConditionDynamicSizeView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericAlwaysFalseConditionDynamicSizeView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeAlwaysFalseConditionDynamicSizeView( T &&emboss_reserved_local_arg) {
+  return GenericAlwaysFalseConditionDynamicSizeView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericAlwaysFalseConditionDynamicSizeView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeAlwaysFalseConditionDynamicSizeView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericAlwaysFalseConditionDynamicSizeView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericAlwaysFalseConditionDynamicSizeView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedAlwaysFalseConditionDynamicSizeView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericAlwaysFalseConditionDynamicSizeView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace ConditionDoesNotContributeToSize {
+
+}  // namespace ConditionDoesNotContributeToSize
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericConditionDoesNotContributeToSizeView;
+
+template <class Storage>
+class GenericConditionDoesNotContributeToSizeView final {
+ public:
+  GenericConditionDoesNotContributeToSizeView() : backing_() {}
+  explicit GenericConditionDoesNotContributeToSizeView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericConditionDoesNotContributeToSizeView(
+      const GenericConditionDoesNotContributeToSizeView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericConditionDoesNotContributeToSizeView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericConditionDoesNotContributeToSizeView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericConditionDoesNotContributeToSizeView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericConditionDoesNotContributeToSizeView<Storage> &operator=(
+      const GenericConditionDoesNotContributeToSizeView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_xc().Known()) return false;
+    if (has_xc().ValueOrDefault() && !xc().Ok()) return false;
+
+
+    if (!has_y().Known()) return false;
+    if (has_y().ValueOrDefault() && !y().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericConditionDoesNotContributeToSizeView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_xc().Known()) return false;
+    if (!emboss_reserved_local_other.has_xc().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        !has_xc().ValueOrDefault())
+      return false;
+    if (has_xc().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xc().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        has_xc().ValueOrDefault() &&
+        !xc().Equals(emboss_reserved_local_other.xc()))
+      return false;
+
+
+
+    if (!has_y().Known()) return false;
+    if (!emboss_reserved_local_other.has_y().Known()) return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
+        !has_y().ValueOrDefault())
+      return false;
+    if (has_y().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_y().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
+        has_y().ValueOrDefault() &&
+        !y().Equals(emboss_reserved_local_other.y()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericConditionDoesNotContributeToSizeView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        !has_xc().ValueOr(false))
+      return false;
+    if (has_xc().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xc().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        has_xc().ValueOr(false) &&
+        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
+        !has_y().ValueOr(false))
+      return false;
+    if (has_y().ValueOr(false) &&
+        !emboss_reserved_local_other.has_y().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
+        has_y().ValueOr(false) &&
+        !y().UncheckedEquals(emboss_reserved_local_other.y()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericConditionDoesNotContributeToSizeView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericConditionDoesNotContributeToSizeView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericConditionDoesNotContributeToSizeView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "xc") {
+        if (!xc().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "y") {
+        if (!y().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_xc().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xc().IsAggregate() || xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xc: ");
+        xc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xc().IsAggregate() && !xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xc: UNREADABLE\n");
+      }
+    }
+
+    if (has_y().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          y().IsAggregate() || y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("y: ");
+        y().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !y().IsAggregate() && !y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# y: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ xc() const;
+  ::emboss::support::Maybe<bool> has_xc() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ y() const;
+  ::emboss::support::Maybe<bool> has_y() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericConditionDoesNotContributeToSizeView;
+};
+using ConditionDoesNotContributeToSizeView =
+    GenericConditionDoesNotContributeToSizeView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ConditionDoesNotContributeToSizeWriter =
+    GenericConditionDoesNotContributeToSizeView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericConditionDoesNotContributeToSizeView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericConditionDoesNotContributeToSizeView<
+    GenericConditionDoesNotContributeToSizeView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericConditionDoesNotContributeToSizeView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeConditionDoesNotContributeToSizeView( T &&emboss_reserved_local_arg) {
+  return GenericConditionDoesNotContributeToSizeView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericConditionDoesNotContributeToSizeView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeConditionDoesNotContributeToSizeView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericConditionDoesNotContributeToSizeView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericConditionDoesNotContributeToSizeView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedConditionDoesNotContributeToSizeView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericConditionDoesNotContributeToSizeView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+enum class OnOff : ::std::uint64_t {
+  OFF = static_cast</**/::std::int32_t>(0LL),
+  ON = static_cast</**/::std::int32_t>(1LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<OnOff> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   OnOff *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("OFF", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = OnOff::OFF;
+      return true;
+    }
+
+    if (!strcmp("ON", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = OnOff::ON;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      OnOff emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case OnOff::OFF: return "OFF";
+
+      case OnOff::ON: return "ON";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(OnOff emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case OnOff::OFF: return true;
+
+      case OnOff::ON: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       OnOff emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<OnOff>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    OnOff *emboss_reserved_local_result) {
+  return EnumTraits<OnOff>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    OnOff emboss_reserved_local_value) {
+  return EnumTraits<OnOff>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(OnOff emboss_reserved_local_value) {
+  return EnumTraits<OnOff>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    OnOff emboss_reserved_local_value) {
+  return EnumTraits<OnOff>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+
+
+
+
+
+namespace EnumCondition {
+
+}  // namespace EnumCondition
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericEnumConditionView;
+
+template <class Storage>
+class GenericEnumConditionView final {
+ public:
+  GenericEnumConditionView() : backing_() {}
+  explicit GenericEnumConditionView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEnumConditionView(
+      const GenericEnumConditionView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericEnumConditionView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericEnumConditionView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericEnumConditionView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEnumConditionView<Storage> &operator=(
+      const GenericEnumConditionView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_xc().Known()) return false;
+    if (has_xc().ValueOrDefault() && !xc().Ok()) return false;
+
+
+    if (!has_xc2().Known()) return false;
+    if (has_xc2().ValueOrDefault() && !xc2().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericEnumConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_xc().Known()) return false;
+    if (!emboss_reserved_local_other.has_xc().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        !has_xc().ValueOrDefault())
+      return false;
+    if (has_xc().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xc().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        has_xc().ValueOrDefault() &&
+        !xc().Equals(emboss_reserved_local_other.xc()))
+      return false;
+
+
+
+    if (!has_xc2().Known()) return false;
+    if (!emboss_reserved_local_other.has_xc2().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xc2().ValueOrDefault() &&
+        !has_xc2().ValueOrDefault())
+      return false;
+    if (has_xc2().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xc2().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xc2().ValueOrDefault() &&
+        has_xc2().ValueOrDefault() &&
+        !xc2().Equals(emboss_reserved_local_other.xc2()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericEnumConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        !has_xc().ValueOr(false))
+      return false;
+    if (has_xc().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xc().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        has_xc().ValueOr(false) &&
+        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_xc2().ValueOr(false) &&
+        !has_xc2().ValueOr(false))
+      return false;
+    if (has_xc2().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xc2().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xc2().ValueOr(false) &&
+        has_xc2().ValueOr(false) &&
+        !xc2().UncheckedEquals(emboss_reserved_local_other.xc2()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericEnumConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericEnumConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericEnumConditionView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "xc") {
+        if (!xc().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "xc2") {
+        if (!xc2().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_xc().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xc().IsAggregate() || xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xc: ");
+        xc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xc().IsAggregate() && !xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xc: UNREADABLE\n");
+      }
+    }
+
+    if (has_xc2().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xc2().IsAggregate() || xc2().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xc2: ");
+        xc2().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xc2().IsAggregate() && !xc2().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xc2: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::OnOff,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ xc() const;
+  ::emboss::support::Maybe<bool> has_xc() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ xc2() const;
+  ::emboss::support::Maybe<bool> has_xc2() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericEnumConditionView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::emboss::test::OnOff>(static_cast</**/::emboss::test::OnOff>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::OnOff>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Equal</**/::emboss::test::OnOff, bool, ::emboss::test::OnOff, ::emboss::test::OnOff>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::emboss::test::OnOff>(static_cast</**/::emboss::test::OnOff>(1)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::GreaterThan</**/::emboss::test::OnOff, bool, ::emboss::test::OnOff, ::emboss::test::OnOff>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::emboss::test::OnOff>(static_cast</**/::emboss::test::OnOff>(0)));
+      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_5, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_4, emboss_reserved_local_subexpr_6);
+
+      return emboss_reserved_local_subexpr_7;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericEnumConditionView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericEnumConditionView;
+};
+using EnumConditionView =
+    GenericEnumConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using EnumConditionWriter =
+    GenericEnumConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericEnumConditionView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericEnumConditionView<
+    GenericEnumConditionView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericEnumConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeEnumConditionView( T &&emboss_reserved_local_arg) {
+  return GenericEnumConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericEnumConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeEnumConditionView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericEnumConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericEnumConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedEnumConditionView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericEnumConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace NegativeEnumCondition {
+
+}  // namespace NegativeEnumCondition
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericNegativeEnumConditionView;
+
+template <class Storage>
+class GenericNegativeEnumConditionView final {
+ public:
+  GenericNegativeEnumConditionView() : backing_() {}
+  explicit GenericNegativeEnumConditionView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericNegativeEnumConditionView(
+      const GenericNegativeEnumConditionView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericNegativeEnumConditionView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericNegativeEnumConditionView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericNegativeEnumConditionView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericNegativeEnumConditionView<Storage> &operator=(
+      const GenericNegativeEnumConditionView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_xc().Known()) return false;
+    if (has_xc().ValueOrDefault() && !xc().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericNegativeEnumConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_xc().Known()) return false;
+    if (!emboss_reserved_local_other.has_xc().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        !has_xc().ValueOrDefault())
+      return false;
+    if (has_xc().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xc().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        has_xc().ValueOrDefault() &&
+        !xc().Equals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericNegativeEnumConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        !has_xc().ValueOr(false))
+      return false;
+    if (has_xc().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xc().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        has_xc().ValueOr(false) &&
+        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericNegativeEnumConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericNegativeEnumConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericNegativeEnumConditionView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "xc") {
+        if (!xc().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_xc().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xc().IsAggregate() || xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xc: ");
+        xc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xc().IsAggregate() && !xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xc: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::OnOff,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ xc() const;
+  ::emboss::support::Maybe<bool> has_xc() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericNegativeEnumConditionView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::emboss::test::OnOff>(static_cast</**/::emboss::test::OnOff>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::OnOff>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::NotEqual</**/::emboss::test::OnOff, bool, ::emboss::test::OnOff, ::emboss::test::OnOff>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::emboss::test::OnOff>(static_cast</**/::emboss::test::OnOff>(1)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_4);
+
+      return emboss_reserved_local_subexpr_5;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericNegativeEnumConditionView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericNegativeEnumConditionView;
+};
+using NegativeEnumConditionView =
+    GenericNegativeEnumConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using NegativeEnumConditionWriter =
+    GenericNegativeEnumConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericNegativeEnumConditionView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericNegativeEnumConditionView<
+    GenericNegativeEnumConditionView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericNegativeEnumConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeNegativeEnumConditionView( T &&emboss_reserved_local_arg) {
+  return GenericNegativeEnumConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericNegativeEnumConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeNegativeEnumConditionView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericNegativeEnumConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericNegativeEnumConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedNegativeEnumConditionView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericNegativeEnumConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace LessThanCondition {
+
+}  // namespace LessThanCondition
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericLessThanConditionView;
+
+template <class Storage>
+class GenericLessThanConditionView final {
+ public:
+  GenericLessThanConditionView() : backing_() {}
+  explicit GenericLessThanConditionView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericLessThanConditionView(
+      const GenericLessThanConditionView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericLessThanConditionView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericLessThanConditionView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericLessThanConditionView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericLessThanConditionView<Storage> &operator=(
+      const GenericLessThanConditionView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_xc().Known()) return false;
+    if (has_xc().ValueOrDefault() && !xc().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericLessThanConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_xc().Known()) return false;
+    if (!emboss_reserved_local_other.has_xc().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        !has_xc().ValueOrDefault())
+      return false;
+    if (has_xc().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xc().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        has_xc().ValueOrDefault() &&
+        !xc().Equals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericLessThanConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        !has_xc().ValueOr(false))
+      return false;
+    if (has_xc().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xc().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        has_xc().ValueOr(false) &&
+        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericLessThanConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericLessThanConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericLessThanConditionView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "xc") {
+        if (!xc().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_xc().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xc().IsAggregate() || xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xc: ");
+        xc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xc().IsAggregate() && !xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xc: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ xc() const;
+  ::emboss::support::Maybe<bool> has_xc() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericLessThanConditionView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::LessThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_4);
+
+      return emboss_reserved_local_subexpr_5;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericLessThanConditionView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericLessThanConditionView;
+};
+using LessThanConditionView =
+    GenericLessThanConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using LessThanConditionWriter =
+    GenericLessThanConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericLessThanConditionView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericLessThanConditionView<
+    GenericLessThanConditionView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericLessThanConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeLessThanConditionView( T &&emboss_reserved_local_arg) {
+  return GenericLessThanConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericLessThanConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeLessThanConditionView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericLessThanConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericLessThanConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedLessThanConditionView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericLessThanConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace LessThanOrEqualCondition {
+
+}  // namespace LessThanOrEqualCondition
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericLessThanOrEqualConditionView;
+
+template <class Storage>
+class GenericLessThanOrEqualConditionView final {
+ public:
+  GenericLessThanOrEqualConditionView() : backing_() {}
+  explicit GenericLessThanOrEqualConditionView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericLessThanOrEqualConditionView(
+      const GenericLessThanOrEqualConditionView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericLessThanOrEqualConditionView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericLessThanOrEqualConditionView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericLessThanOrEqualConditionView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericLessThanOrEqualConditionView<Storage> &operator=(
+      const GenericLessThanOrEqualConditionView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_xc().Known()) return false;
+    if (has_xc().ValueOrDefault() && !xc().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericLessThanOrEqualConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_xc().Known()) return false;
+    if (!emboss_reserved_local_other.has_xc().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        !has_xc().ValueOrDefault())
+      return false;
+    if (has_xc().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xc().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        has_xc().ValueOrDefault() &&
+        !xc().Equals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericLessThanOrEqualConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        !has_xc().ValueOr(false))
+      return false;
+    if (has_xc().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xc().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        has_xc().ValueOr(false) &&
+        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericLessThanOrEqualConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericLessThanOrEqualConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericLessThanOrEqualConditionView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "xc") {
+        if (!xc().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_xc().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xc().IsAggregate() || xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xc: ");
+        xc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xc().IsAggregate() && !xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xc: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ xc() const;
+  ::emboss::support::Maybe<bool> has_xc() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericLessThanOrEqualConditionView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_4);
+
+      return emboss_reserved_local_subexpr_5;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericLessThanOrEqualConditionView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericLessThanOrEqualConditionView;
+};
+using LessThanOrEqualConditionView =
+    GenericLessThanOrEqualConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using LessThanOrEqualConditionWriter =
+    GenericLessThanOrEqualConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericLessThanOrEqualConditionView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericLessThanOrEqualConditionView<
+    GenericLessThanOrEqualConditionView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericLessThanOrEqualConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeLessThanOrEqualConditionView( T &&emboss_reserved_local_arg) {
+  return GenericLessThanOrEqualConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericLessThanOrEqualConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeLessThanOrEqualConditionView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericLessThanOrEqualConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericLessThanOrEqualConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedLessThanOrEqualConditionView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericLessThanOrEqualConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace GreaterThanOrEqualCondition {
+
+}  // namespace GreaterThanOrEqualCondition
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericGreaterThanOrEqualConditionView;
+
+template <class Storage>
+class GenericGreaterThanOrEqualConditionView final {
+ public:
+  GenericGreaterThanOrEqualConditionView() : backing_() {}
+  explicit GenericGreaterThanOrEqualConditionView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericGreaterThanOrEqualConditionView(
+      const GenericGreaterThanOrEqualConditionView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericGreaterThanOrEqualConditionView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericGreaterThanOrEqualConditionView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericGreaterThanOrEqualConditionView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericGreaterThanOrEqualConditionView<Storage> &operator=(
+      const GenericGreaterThanOrEqualConditionView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_xc().Known()) return false;
+    if (has_xc().ValueOrDefault() && !xc().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericGreaterThanOrEqualConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_xc().Known()) return false;
+    if (!emboss_reserved_local_other.has_xc().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        !has_xc().ValueOrDefault())
+      return false;
+    if (has_xc().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xc().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        has_xc().ValueOrDefault() &&
+        !xc().Equals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericGreaterThanOrEqualConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        !has_xc().ValueOr(false))
+      return false;
+    if (has_xc().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xc().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        has_xc().ValueOr(false) &&
+        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericGreaterThanOrEqualConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericGreaterThanOrEqualConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericGreaterThanOrEqualConditionView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "xc") {
+        if (!xc().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_xc().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xc().IsAggregate() || xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xc: ");
+        xc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xc().IsAggregate() && !xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xc: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ xc() const;
+  ::emboss::support::Maybe<bool> has_xc() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericGreaterThanOrEqualConditionView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::GreaterThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_4);
+
+      return emboss_reserved_local_subexpr_5;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericGreaterThanOrEqualConditionView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericGreaterThanOrEqualConditionView;
+};
+using GreaterThanOrEqualConditionView =
+    GenericGreaterThanOrEqualConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using GreaterThanOrEqualConditionWriter =
+    GenericGreaterThanOrEqualConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericGreaterThanOrEqualConditionView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericGreaterThanOrEqualConditionView<
+    GenericGreaterThanOrEqualConditionView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericGreaterThanOrEqualConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeGreaterThanOrEqualConditionView( T &&emboss_reserved_local_arg) {
+  return GenericGreaterThanOrEqualConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericGreaterThanOrEqualConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeGreaterThanOrEqualConditionView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericGreaterThanOrEqualConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericGreaterThanOrEqualConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedGreaterThanOrEqualConditionView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericGreaterThanOrEqualConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace GreaterThanCondition {
+
+}  // namespace GreaterThanCondition
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericGreaterThanConditionView;
+
+template <class Storage>
+class GenericGreaterThanConditionView final {
+ public:
+  GenericGreaterThanConditionView() : backing_() {}
+  explicit GenericGreaterThanConditionView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericGreaterThanConditionView(
+      const GenericGreaterThanConditionView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericGreaterThanConditionView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericGreaterThanConditionView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericGreaterThanConditionView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericGreaterThanConditionView<Storage> &operator=(
+      const GenericGreaterThanConditionView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_xc().Known()) return false;
+    if (has_xc().ValueOrDefault() && !xc().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericGreaterThanConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_xc().Known()) return false;
+    if (!emboss_reserved_local_other.has_xc().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        !has_xc().ValueOrDefault())
+      return false;
+    if (has_xc().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xc().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        has_xc().ValueOrDefault() &&
+        !xc().Equals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericGreaterThanConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        !has_xc().ValueOr(false))
+      return false;
+    if (has_xc().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xc().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        has_xc().ValueOr(false) &&
+        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericGreaterThanConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericGreaterThanConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericGreaterThanConditionView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "xc") {
+        if (!xc().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_xc().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xc().IsAggregate() || xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xc: ");
+        xc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xc().IsAggregate() && !xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xc: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ xc() const;
+  ::emboss::support::Maybe<bool> has_xc() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericGreaterThanConditionView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_4);
+
+      return emboss_reserved_local_subexpr_5;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericGreaterThanConditionView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericGreaterThanConditionView;
+};
+using GreaterThanConditionView =
+    GenericGreaterThanConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using GreaterThanConditionWriter =
+    GenericGreaterThanConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericGreaterThanConditionView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericGreaterThanConditionView<
+    GenericGreaterThanConditionView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericGreaterThanConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeGreaterThanConditionView( T &&emboss_reserved_local_arg) {
+  return GenericGreaterThanConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericGreaterThanConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeGreaterThanConditionView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericGreaterThanConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericGreaterThanConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedGreaterThanConditionView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericGreaterThanConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace RangeCondition {
+
+}  // namespace RangeCondition
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericRangeConditionView;
+
+template <class Storage>
+class GenericRangeConditionView final {
+ public:
+  GenericRangeConditionView() : backing_() {}
+  explicit GenericRangeConditionView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericRangeConditionView(
+      const GenericRangeConditionView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericRangeConditionView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericRangeConditionView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericRangeConditionView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericRangeConditionView<Storage> &operator=(
+      const GenericRangeConditionView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_y().Known()) return false;
+    if (has_y().ValueOrDefault() && !y().Ok()) return false;
+
+
+    if (!has_xc().Known()) return false;
+    if (has_xc().ValueOrDefault() && !xc().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericRangeConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_y().Known()) return false;
+    if (!emboss_reserved_local_other.has_y().Known()) return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
+        !has_y().ValueOrDefault())
+      return false;
+    if (has_y().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_y().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
+        has_y().ValueOrDefault() &&
+        !y().Equals(emboss_reserved_local_other.y()))
+      return false;
+
+
+
+    if (!has_xc().Known()) return false;
+    if (!emboss_reserved_local_other.has_xc().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        !has_xc().ValueOrDefault())
+      return false;
+    if (has_xc().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xc().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        has_xc().ValueOrDefault() &&
+        !xc().Equals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericRangeConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
+        !has_y().ValueOr(false))
+      return false;
+    if (has_y().ValueOr(false) &&
+        !emboss_reserved_local_other.has_y().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
+        has_y().ValueOr(false) &&
+        !y().UncheckedEquals(emboss_reserved_local_other.y()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        !has_xc().ValueOr(false))
+      return false;
+    if (has_xc().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xc().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        has_xc().ValueOr(false) &&
+        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericRangeConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericRangeConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericRangeConditionView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "y") {
+        if (!y().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "xc") {
+        if (!xc().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_y().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          y().IsAggregate() || y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("y: ");
+        y().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !y().IsAggregate() && !y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# y: UNREADABLE\n");
+      }
+    }
+
+    if (has_xc().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xc().IsAggregate() || xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xc: ");
+        xc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xc().IsAggregate() && !xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xc: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ y() const;
+  ::emboss::support::Maybe<bool> has_y() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ xc() const;
+  ::emboss::support::Maybe<bool> has_xc() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericRangeConditionView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::LessThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)), emboss_reserved_local_subexpr_2);
+      const auto emboss_reserved_local_subexpr_4 = view_.y();
+      const auto emboss_reserved_local_subexpr_5 = (emboss_reserved_local_subexpr_4.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_4.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_5);
+      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::And</**/bool, bool, bool, bool>(emboss_reserved_local_subexpr_3, emboss_reserved_local_subexpr_6);
+      const auto emboss_reserved_local_subexpr_8 = ::emboss::support::LessThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_5, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)));
+      const auto emboss_reserved_local_subexpr_9 = ::emboss::support::And</**/bool, bool, bool, bool>(emboss_reserved_local_subexpr_7, emboss_reserved_local_subexpr_8);
+      const auto emboss_reserved_local_subexpr_10 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_9, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_11 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), emboss_reserved_local_subexpr_10);
+
+      return emboss_reserved_local_subexpr_11;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericRangeConditionView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericRangeConditionView;
+};
+using RangeConditionView =
+    GenericRangeConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using RangeConditionWriter =
+    GenericRangeConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericRangeConditionView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericRangeConditionView<
+    GenericRangeConditionView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericRangeConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeRangeConditionView( T &&emboss_reserved_local_arg) {
+  return GenericRangeConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericRangeConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeRangeConditionView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericRangeConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericRangeConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedRangeConditionView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericRangeConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace ReverseRangeCondition {
+
+}  // namespace ReverseRangeCondition
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericReverseRangeConditionView;
+
+template <class Storage>
+class GenericReverseRangeConditionView final {
+ public:
+  GenericReverseRangeConditionView() : backing_() {}
+  explicit GenericReverseRangeConditionView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericReverseRangeConditionView(
+      const GenericReverseRangeConditionView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericReverseRangeConditionView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericReverseRangeConditionView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericReverseRangeConditionView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericReverseRangeConditionView<Storage> &operator=(
+      const GenericReverseRangeConditionView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_y().Known()) return false;
+    if (has_y().ValueOrDefault() && !y().Ok()) return false;
+
+
+    if (!has_xc().Known()) return false;
+    if (has_xc().ValueOrDefault() && !xc().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericReverseRangeConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_y().Known()) return false;
+    if (!emboss_reserved_local_other.has_y().Known()) return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
+        !has_y().ValueOrDefault())
+      return false;
+    if (has_y().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_y().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
+        has_y().ValueOrDefault() &&
+        !y().Equals(emboss_reserved_local_other.y()))
+      return false;
+
+
+
+    if (!has_xc().Known()) return false;
+    if (!emboss_reserved_local_other.has_xc().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        !has_xc().ValueOrDefault())
+      return false;
+    if (has_xc().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xc().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        has_xc().ValueOrDefault() &&
+        !xc().Equals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericReverseRangeConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
+        !has_y().ValueOr(false))
+      return false;
+    if (has_y().ValueOr(false) &&
+        !emboss_reserved_local_other.has_y().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
+        has_y().ValueOr(false) &&
+        !y().UncheckedEquals(emboss_reserved_local_other.y()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        !has_xc().ValueOr(false))
+      return false;
+    if (has_xc().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xc().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        has_xc().ValueOr(false) &&
+        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericReverseRangeConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericReverseRangeConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericReverseRangeConditionView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "y") {
+        if (!y().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "xc") {
+        if (!xc().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_y().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          y().IsAggregate() || y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("y: ");
+        y().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !y().IsAggregate() && !y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# y: UNREADABLE\n");
+      }
+    }
+
+    if (has_xc().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xc().IsAggregate() || xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xc: ");
+        xc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xc().IsAggregate() && !xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xc: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ y() const;
+  ::emboss::support::Maybe<bool> has_y() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ xc() const;
+  ::emboss::support::Maybe<bool> has_xc() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericReverseRangeConditionView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.y();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)), emboss_reserved_local_subexpr_2);
+      const auto emboss_reserved_local_subexpr_4 = view_.x();
+      const auto emboss_reserved_local_subexpr_5 = (emboss_reserved_local_subexpr_4.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_4.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::GreaterThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_5);
+      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::And</**/bool, bool, bool, bool>(emboss_reserved_local_subexpr_3, emboss_reserved_local_subexpr_6);
+      const auto emboss_reserved_local_subexpr_8 = ::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_5, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
+      const auto emboss_reserved_local_subexpr_9 = ::emboss::support::And</**/bool, bool, bool, bool>(emboss_reserved_local_subexpr_7, emboss_reserved_local_subexpr_8);
+      const auto emboss_reserved_local_subexpr_10 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_9, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_11 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), emboss_reserved_local_subexpr_10);
+
+      return emboss_reserved_local_subexpr_11;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericReverseRangeConditionView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericReverseRangeConditionView;
+};
+using ReverseRangeConditionView =
+    GenericReverseRangeConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ReverseRangeConditionWriter =
+    GenericReverseRangeConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericReverseRangeConditionView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericReverseRangeConditionView<
+    GenericReverseRangeConditionView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericReverseRangeConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeReverseRangeConditionView( T &&emboss_reserved_local_arg) {
+  return GenericReverseRangeConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericReverseRangeConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeReverseRangeConditionView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericReverseRangeConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericReverseRangeConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedReverseRangeConditionView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericReverseRangeConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace AndCondition {
+
+}  // namespace AndCondition
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericAndConditionView;
+
+template <class Storage>
+class GenericAndConditionView final {
+ public:
+  GenericAndConditionView() : backing_() {}
+  explicit GenericAndConditionView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericAndConditionView(
+      const GenericAndConditionView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericAndConditionView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericAndConditionView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericAndConditionView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericAndConditionView<Storage> &operator=(
+      const GenericAndConditionView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_y().Known()) return false;
+    if (has_y().ValueOrDefault() && !y().Ok()) return false;
+
+
+    if (!has_xc().Known()) return false;
+    if (has_xc().ValueOrDefault() && !xc().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericAndConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_y().Known()) return false;
+    if (!emboss_reserved_local_other.has_y().Known()) return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
+        !has_y().ValueOrDefault())
+      return false;
+    if (has_y().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_y().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
+        has_y().ValueOrDefault() &&
+        !y().Equals(emboss_reserved_local_other.y()))
+      return false;
+
+
+
+    if (!has_xc().Known()) return false;
+    if (!emboss_reserved_local_other.has_xc().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        !has_xc().ValueOrDefault())
+      return false;
+    if (has_xc().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xc().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        has_xc().ValueOrDefault() &&
+        !xc().Equals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericAndConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
+        !has_y().ValueOr(false))
+      return false;
+    if (has_y().ValueOr(false) &&
+        !emboss_reserved_local_other.has_y().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
+        has_y().ValueOr(false) &&
+        !y().UncheckedEquals(emboss_reserved_local_other.y()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        !has_xc().ValueOr(false))
+      return false;
+    if (has_xc().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xc().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        has_xc().ValueOr(false) &&
+        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericAndConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericAndConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericAndConditionView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "y") {
+        if (!y().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "xc") {
+        if (!xc().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_y().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          y().IsAggregate() || y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("y: ");
+        y().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !y().IsAggregate() && !y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# y: UNREADABLE\n");
+      }
+    }
+
+    if (has_xc().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xc().IsAggregate() || xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xc: ");
+        xc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xc().IsAggregate() && !xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xc: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ y() const;
+  ::emboss::support::Maybe<bool> has_y() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ xc() const;
+  ::emboss::support::Maybe<bool> has_xc() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericAndConditionView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
+      const auto emboss_reserved_local_subexpr_4 = view_.y();
+      const auto emboss_reserved_local_subexpr_5 = (emboss_reserved_local_subexpr_4.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_4.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_5, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
+      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::And</**/bool, bool, bool, bool>(emboss_reserved_local_subexpr_3, emboss_reserved_local_subexpr_6);
+      const auto emboss_reserved_local_subexpr_8 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_7, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_9 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), emboss_reserved_local_subexpr_8);
+
+      return emboss_reserved_local_subexpr_9;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericAndConditionView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericAndConditionView;
+};
+using AndConditionView =
+    GenericAndConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using AndConditionWriter =
+    GenericAndConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericAndConditionView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericAndConditionView<
+    GenericAndConditionView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericAndConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeAndConditionView( T &&emboss_reserved_local_arg) {
+  return GenericAndConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericAndConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeAndConditionView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericAndConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericAndConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedAndConditionView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericAndConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace OrCondition {
+
+}  // namespace OrCondition
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericOrConditionView;
+
+template <class Storage>
+class GenericOrConditionView final {
+ public:
+  GenericOrConditionView() : backing_() {}
+  explicit GenericOrConditionView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericOrConditionView(
+      const GenericOrConditionView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericOrConditionView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericOrConditionView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericOrConditionView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericOrConditionView<Storage> &operator=(
+      const GenericOrConditionView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_y().Known()) return false;
+    if (has_y().ValueOrDefault() && !y().Ok()) return false;
+
+
+    if (!has_xc().Known()) return false;
+    if (has_xc().ValueOrDefault() && !xc().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericOrConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_y().Known()) return false;
+    if (!emboss_reserved_local_other.has_y().Known()) return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
+        !has_y().ValueOrDefault())
+      return false;
+    if (has_y().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_y().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
+        has_y().ValueOrDefault() &&
+        !y().Equals(emboss_reserved_local_other.y()))
+      return false;
+
+
+
+    if (!has_xc().Known()) return false;
+    if (!emboss_reserved_local_other.has_xc().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        !has_xc().ValueOrDefault())
+      return false;
+    if (has_xc().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xc().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        has_xc().ValueOrDefault() &&
+        !xc().Equals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericOrConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
+        !has_y().ValueOr(false))
+      return false;
+    if (has_y().ValueOr(false) &&
+        !emboss_reserved_local_other.has_y().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
+        has_y().ValueOr(false) &&
+        !y().UncheckedEquals(emboss_reserved_local_other.y()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        !has_xc().ValueOr(false))
+      return false;
+    if (has_xc().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xc().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        has_xc().ValueOr(false) &&
+        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericOrConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericOrConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericOrConditionView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "y") {
+        if (!y().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "xc") {
+        if (!xc().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_y().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          y().IsAggregate() || y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("y: ");
+        y().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !y().IsAggregate() && !y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# y: UNREADABLE\n");
+      }
+    }
+
+    if (has_xc().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xc().IsAggregate() || xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xc: ");
+        xc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xc().IsAggregate() && !xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xc: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ y() const;
+  ::emboss::support::Maybe<bool> has_y() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ xc() const;
+  ::emboss::support::Maybe<bool> has_xc() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericOrConditionView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
+      const auto emboss_reserved_local_subexpr_4 = view_.y();
+      const auto emboss_reserved_local_subexpr_5 = (emboss_reserved_local_subexpr_4.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_4.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_5, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
+      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::Or</**/bool, bool, bool, bool>(emboss_reserved_local_subexpr_3, emboss_reserved_local_subexpr_6);
+      const auto emboss_reserved_local_subexpr_8 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_7, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_9 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), emboss_reserved_local_subexpr_8);
+
+      return emboss_reserved_local_subexpr_9;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericOrConditionView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericOrConditionView;
+};
+using OrConditionView =
+    GenericOrConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using OrConditionWriter =
+    GenericOrConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericOrConditionView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericOrConditionView<
+    GenericOrConditionView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericOrConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeOrConditionView( T &&emboss_reserved_local_arg) {
+  return GenericOrConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericOrConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeOrConditionView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericOrConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericOrConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedOrConditionView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericOrConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+
+namespace ChoiceCondition {
+enum class Field : ::std::uint64_t {
+  USE_X = static_cast</**/::std::int32_t>(1LL),
+  USE_Y = static_cast</**/::std::int32_t>(2LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<Field> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   Field *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("USE_X", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Field::USE_X;
+      return true;
+    }
+
+    if (!strcmp("USE_Y", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Field::USE_Y;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      Field emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Field::USE_X: return "USE_X";
+
+      case Field::USE_Y: return "USE_Y";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(Field emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Field::USE_X: return true;
+
+      case Field::USE_Y: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       Field emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<Field>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    Field *emboss_reserved_local_result) {
+  return EnumTraits<Field>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    Field emboss_reserved_local_value) {
+  return EnumTraits<Field>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(Field emboss_reserved_local_value) {
+  return EnumTraits<Field>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    Field emboss_reserved_local_value) {
+  return EnumTraits<Field>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+
+}  // namespace ChoiceCondition
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericChoiceConditionView;
+
+template <class Storage>
+class GenericChoiceConditionView final {
+ public:
+  GenericChoiceConditionView() : backing_() {}
+  explicit GenericChoiceConditionView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericChoiceConditionView(
+      const GenericChoiceConditionView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericChoiceConditionView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericChoiceConditionView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericChoiceConditionView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericChoiceConditionView<Storage> &operator=(
+      const GenericChoiceConditionView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+    using Field = ::emboss::test::ChoiceCondition::Field;
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_field().Known()) return false;
+    if (has_field().ValueOrDefault() && !field().Ok()) return false;
+
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_y().Known()) return false;
+    if (has_y().ValueOrDefault() && !y().Ok()) return false;
+
+
+    if (!has_xyc().Known()) return false;
+    if (has_xyc().ValueOrDefault() && !xyc().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericChoiceConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_field().Known()) return false;
+    if (!emboss_reserved_local_other.has_field().Known()) return false;
+
+    if (emboss_reserved_local_other.has_field().ValueOrDefault() &&
+        !has_field().ValueOrDefault())
+      return false;
+    if (has_field().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_field().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_field().ValueOrDefault() &&
+        has_field().ValueOrDefault() &&
+        !field().Equals(emboss_reserved_local_other.field()))
+      return false;
+
+
+
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_y().Known()) return false;
+    if (!emboss_reserved_local_other.has_y().Known()) return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
+        !has_y().ValueOrDefault())
+      return false;
+    if (has_y().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_y().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
+        has_y().ValueOrDefault() &&
+        !y().Equals(emboss_reserved_local_other.y()))
+      return false;
+
+
+
+    if (!has_xyc().Known()) return false;
+    if (!emboss_reserved_local_other.has_xyc().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xyc().ValueOrDefault() &&
+        !has_xyc().ValueOrDefault())
+      return false;
+    if (has_xyc().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xyc().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xyc().ValueOrDefault() &&
+        has_xyc().ValueOrDefault() &&
+        !xyc().Equals(emboss_reserved_local_other.xyc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericChoiceConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_field().ValueOr(false) &&
+        !has_field().ValueOr(false))
+      return false;
+    if (has_field().ValueOr(false) &&
+        !emboss_reserved_local_other.has_field().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_field().ValueOr(false) &&
+        has_field().ValueOr(false) &&
+        !field().UncheckedEquals(emboss_reserved_local_other.field()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
+        !has_y().ValueOr(false))
+      return false;
+    if (has_y().ValueOr(false) &&
+        !emboss_reserved_local_other.has_y().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
+        has_y().ValueOr(false) &&
+        !y().UncheckedEquals(emboss_reserved_local_other.y()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_xyc().ValueOr(false) &&
+        !has_xyc().ValueOr(false))
+      return false;
+    if (has_xyc().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xyc().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xyc().ValueOr(false) &&
+        has_xyc().ValueOr(false) &&
+        !xyc().UncheckedEquals(emboss_reserved_local_other.xyc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericChoiceConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericChoiceConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericChoiceConditionView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "field") {
+        if (!field().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "y") {
+        if (!y().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "xyc") {
+        if (!xyc().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_field().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          field().IsAggregate() || field().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("field: ");
+        field().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !field().IsAggregate() && !field().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# field: UNREADABLE\n");
+      }
+    }
+
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_y().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          y().IsAggregate() || y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("y: ");
+        y().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !y().IsAggregate() && !y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# y: UNREADABLE\n");
+      }
+    }
+
+    if (has_xyc().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xyc().IsAggregate() || xyc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xyc: ");
+        xyc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xyc().IsAggregate() && !xyc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xyc: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::ChoiceCondition::Field,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ field() const;
+  ::emboss::support::Maybe<bool> has_field() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ y() const;
+  ::emboss::support::Maybe<bool> has_y() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 8>>
+
+ xyc() const;
+  ::emboss::support::Maybe<bool> has_xyc() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericChoiceConditionView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.field();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::emboss::test::ChoiceCondition::Field>(static_cast</**/::emboss::test::ChoiceCondition::Field>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::ChoiceCondition::Field>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Equal</**/::emboss::test::ChoiceCondition::Field, bool, ::emboss::test::ChoiceCondition::Field, ::emboss::test::ChoiceCondition::Field>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::emboss::test::ChoiceCondition::Field>(static_cast</**/::emboss::test::ChoiceCondition::Field>(1)));
+      const auto emboss_reserved_local_subexpr_4 = view_.x();
+      const auto emboss_reserved_local_subexpr_5 = (emboss_reserved_local_subexpr_4.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_4.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_6 = view_.y();
+      const auto emboss_reserved_local_subexpr_7 = (emboss_reserved_local_subexpr_6.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_6.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_8 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, emboss_reserved_local_subexpr_5, emboss_reserved_local_subexpr_7);
+      const auto emboss_reserved_local_subexpr_9 = ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_8, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
+      const auto emboss_reserved_local_subexpr_10 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_9, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_11 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)), emboss_reserved_local_subexpr_10);
+
+      return emboss_reserved_local_subexpr_11;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericChoiceConditionView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericChoiceConditionView;
+};
+using ChoiceConditionView =
+    GenericChoiceConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ChoiceConditionWriter =
+    GenericChoiceConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericChoiceConditionView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericChoiceConditionView<
+    GenericChoiceConditionView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericChoiceConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeChoiceConditionView( T &&emboss_reserved_local_arg) {
+  return GenericChoiceConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericChoiceConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeChoiceConditionView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericChoiceConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericChoiceConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedChoiceConditionView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericChoiceConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace ContainsBits {
+
+
+
+
+namespace EmbossReservedAnonymousField3 {
+
+}  // namespace EmbossReservedAnonymousField3
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField3View;
+
+template <class Storage>
+class GenericEmbossReservedAnonymousField3View final {
+ public:
+  GenericEmbossReservedAnonymousField3View() : backing_() {}
+  explicit GenericEmbossReservedAnonymousField3View(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEmbossReservedAnonymousField3View(
+      const GenericEmbossReservedAnonymousField3View<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericEmbossReservedAnonymousField3View<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericEmbossReservedAnonymousField3View(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericEmbossReservedAnonymousField3View(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEmbossReservedAnonymousField3View<Storage> &operator=(
+      const GenericEmbossReservedAnonymousField3View<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_has_top().Known()) return false;
+    if (has_has_top().ValueOrDefault() && !has_top().Ok()) return false;
+
+
+    if (!has_has_bottom().Known()) return false;
+    if (has_has_bottom().ValueOrDefault() && !has_bottom().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBits().Known()) return false;
+    if (has_IntrinsicSizeInBits().ValueOrDefault() && !IntrinsicSizeInBits().Ok()) return false;
+
+
+    if (!has_MaxSizeInBits().Known()) return false;
+    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok()) return false;
+
+
+    if (!has_MinSizeInBits().Known()) return false;
+    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBits().Ok() &&
+           backing_.SizeInBits() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBits().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBits() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBits().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBits().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericEmbossReservedAnonymousField3View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_has_top().Known()) return false;
+    if (!emboss_reserved_local_other.has_has_top().Known()) return false;
+
+    if (emboss_reserved_local_other.has_has_top().ValueOrDefault() &&
+        !has_has_top().ValueOrDefault())
+      return false;
+    if (has_has_top().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_has_top().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_has_top().ValueOrDefault() &&
+        has_has_top().ValueOrDefault() &&
+        !has_top().Equals(emboss_reserved_local_other.has_top()))
+      return false;
+
+
+
+    if (!has_has_bottom().Known()) return false;
+    if (!emboss_reserved_local_other.has_has_bottom().Known()) return false;
+
+    if (emboss_reserved_local_other.has_has_bottom().ValueOrDefault() &&
+        !has_has_bottom().ValueOrDefault())
+      return false;
+    if (has_has_bottom().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_has_bottom().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_has_bottom().ValueOrDefault() &&
+        has_has_bottom().ValueOrDefault() &&
+        !has_bottom().Equals(emboss_reserved_local_other.has_bottom()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericEmbossReservedAnonymousField3View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_has_top().ValueOr(false) &&
+        !has_has_top().ValueOr(false))
+      return false;
+    if (has_has_top().ValueOr(false) &&
+        !emboss_reserved_local_other.has_has_top().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_has_top().ValueOr(false) &&
+        has_has_top().ValueOr(false) &&
+        !has_top().UncheckedEquals(emboss_reserved_local_other.has_top()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_has_bottom().ValueOr(false) &&
+        !has_has_bottom().ValueOr(false))
+      return false;
+    if (has_has_bottom().ValueOr(false) &&
+        !emboss_reserved_local_other.has_has_bottom().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_has_bottom().ValueOr(false) &&
+        has_has_bottom().ValueOr(false) &&
+        !has_bottom().UncheckedEquals(emboss_reserved_local_other.has_bottom()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericEmbossReservedAnonymousField3View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericEmbossReservedAnonymousField3View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericEmbossReservedAnonymousField3View<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "has_top") {
+        if (!has_top().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "has_bottom") {
+        if (!has_bottom().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_has_top().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          has_top().IsAggregate() || has_top().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("has_top: ");
+        has_top().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !has_top().IsAggregate() && !has_top().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# has_top: UNREADABLE\n");
+      }
+    }
+
+    if (has_has_bottom().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          has_bottom().IsAggregate() || has_bottom().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("has_bottom: ");
+        has_bottom().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !has_bottom().IsAggregate() && !has_bottom().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# has_bottom: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 7>>
+
+ has_top() const;
+  ::emboss::support::Maybe<bool> has_has_top() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ has_bottom() const;
+  ::emboss::support::Maybe<bool> has_has_bottom() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView IntrinsicSizeInBits() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBitsView() {}
+    EmbossReservedDollarVirtualMaxSizeInBitsView(const EmbossReservedDollarVirtualMaxSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView(EmbossReservedDollarVirtualMaxSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(const EmbossReservedDollarVirtualMaxSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(EmbossReservedDollarVirtualMaxSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBitsView MaxSizeInBits() {
+    return EmbossReservedDollarVirtualMaxSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBitsView() {}
+    EmbossReservedDollarVirtualMinSizeInBitsView(const EmbossReservedDollarVirtualMinSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView(EmbossReservedDollarVirtualMinSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(const EmbossReservedDollarVirtualMinSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(EmbossReservedDollarVirtualMinSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBitsView MinSizeInBits() {
+    return EmbossReservedDollarVirtualMinSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericEmbossReservedAnonymousField3View;
+};
+using EmbossReservedAnonymousField3View =
+    GenericEmbossReservedAnonymousField3View</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using EmbossReservedAnonymousField3Writer =
+    GenericEmbossReservedAnonymousField3View</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField3View {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField3View<
+    GenericEmbossReservedAnonymousField3View<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericEmbossReservedAnonymousField3View<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeEmbossReservedAnonymousField3View( T &&emboss_reserved_local_arg) {
+  return GenericEmbossReservedAnonymousField3View<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericEmbossReservedAnonymousField3View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeEmbossReservedAnonymousField3View( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericEmbossReservedAnonymousField3View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericEmbossReservedAnonymousField3View<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedEmbossReservedAnonymousField3View(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericEmbossReservedAnonymousField3View<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+}  // namespace ContainsBits
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericContainsBitsView;
+
+template <class Storage>
+class GenericContainsBitsView final {
+ public:
+  GenericContainsBitsView() : backing_() {}
+  explicit GenericContainsBitsView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericContainsBitsView(
+      const GenericContainsBitsView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericContainsBitsView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericContainsBitsView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericContainsBitsView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericContainsBitsView<Storage> &operator=(
+      const GenericContainsBitsView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_emboss_reserved_anonymous_field_3().Known()) return false;
+    if (has_emboss_reserved_anonymous_field_3().ValueOrDefault() && !emboss_reserved_anonymous_field_3().Ok()) return false;
+
+
+    if (!has_has_top().Known()) return false;
+    if (has_has_top().ValueOrDefault() && !has_top().Ok()) return false;
+
+
+    if (!has_has_bottom().Known()) return false;
+    if (has_has_bottom().ValueOrDefault() && !has_bottom().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericContainsBitsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_emboss_reserved_anonymous_field_3().Known()) return false;
+    if (!emboss_reserved_local_other.has_emboss_reserved_anonymous_field_3().Known()) return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_3().ValueOrDefault() &&
+        !has_emboss_reserved_anonymous_field_3().ValueOrDefault())
+      return false;
+    if (has_emboss_reserved_anonymous_field_3().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_emboss_reserved_anonymous_field_3().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_3().ValueOrDefault() &&
+        has_emboss_reserved_anonymous_field_3().ValueOrDefault() &&
+        !emboss_reserved_anonymous_field_3().Equals(emboss_reserved_local_other.emboss_reserved_anonymous_field_3()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericContainsBitsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_3().ValueOr(false) &&
+        !has_emboss_reserved_anonymous_field_3().ValueOr(false))
+      return false;
+    if (has_emboss_reserved_anonymous_field_3().ValueOr(false) &&
+        !emboss_reserved_local_other.has_emboss_reserved_anonymous_field_3().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_3().ValueOr(false) &&
+        has_emboss_reserved_anonymous_field_3().ValueOr(false) &&
+        !emboss_reserved_anonymous_field_3().UncheckedEquals(emboss_reserved_local_other.emboss_reserved_anonymous_field_3()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericContainsBitsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericContainsBitsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericContainsBitsView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "has_top") {
+        if (!has_top().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "has_bottom") {
+        if (!has_bottom().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_has_top().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          has_top().IsAggregate() || has_top().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("has_top: ");
+        has_top().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !has_top().IsAggregate() && !has_top().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# has_top: UNREADABLE\n");
+      }
+    }
+
+    if (has_has_bottom().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          has_bottom().IsAggregate() || has_bottom().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("has_bottom: ");
+        has_bottom().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !has_bottom().IsAggregate() && !has_bottom().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# has_bottom: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ private:
+  typename ::emboss::test::ContainsBits::GenericEmbossReservedAnonymousField3View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ emboss_reserved_anonymous_field_3() const;
+  ::emboss::support::Maybe<bool> has_emboss_reserved_anonymous_field_3() const;
+
+ public:
+  auto has_top() const -> decltype(this->emboss_reserved_anonymous_field_3().has_top()) {
+   return has_has_top().ValueOrDefault() ? emboss_reserved_anonymous_field_3().has_top()
+                                          : decltype(this->emboss_reserved_anonymous_field_3().has_top())();
+  }
+  ::emboss::support::Maybe<bool> has_has_top() const;
+
+ public:
+  auto has_bottom() const -> decltype(this->emboss_reserved_anonymous_field_3().has_bottom()) {
+   return has_has_bottom().ValueOrDefault() ? emboss_reserved_anonymous_field_3().has_bottom()
+                                          : decltype(this->emboss_reserved_anonymous_field_3().has_bottom())();
+  }
+  ::emboss::support::Maybe<bool> has_has_bottom() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericContainsBitsView;
+};
+using ContainsBitsView =
+    GenericContainsBitsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ContainsBitsWriter =
+    GenericContainsBitsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericContainsBitsView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericContainsBitsView<
+    GenericContainsBitsView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericContainsBitsView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeContainsBitsView( T &&emboss_reserved_local_arg) {
+  return GenericContainsBitsView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericContainsBitsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeContainsBitsView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericContainsBitsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericContainsBitsView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedContainsBitsView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericContainsBitsView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace ContainsContainsBits {
+
+}  // namespace ContainsContainsBits
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericContainsContainsBitsView;
+
+template <class Storage>
+class GenericContainsContainsBitsView final {
+ public:
+  GenericContainsContainsBitsView() : backing_() {}
+  explicit GenericContainsContainsBitsView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericContainsContainsBitsView(
+      const GenericContainsContainsBitsView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericContainsContainsBitsView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericContainsContainsBitsView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericContainsContainsBitsView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericContainsContainsBitsView<Storage> &operator=(
+      const GenericContainsContainsBitsView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_condition().Known()) return false;
+    if (has_condition().ValueOrDefault() && !condition().Ok()) return false;
+
+
+    if (!has_top().Known()) return false;
+    if (has_top().ValueOrDefault() && !top().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericContainsContainsBitsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_condition().Known()) return false;
+    if (!emboss_reserved_local_other.has_condition().Known()) return false;
+
+    if (emboss_reserved_local_other.has_condition().ValueOrDefault() &&
+        !has_condition().ValueOrDefault())
+      return false;
+    if (has_condition().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_condition().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_condition().ValueOrDefault() &&
+        has_condition().ValueOrDefault() &&
+        !condition().Equals(emboss_reserved_local_other.condition()))
+      return false;
+
+
+
+    if (!has_top().Known()) return false;
+    if (!emboss_reserved_local_other.has_top().Known()) return false;
+
+    if (emboss_reserved_local_other.has_top().ValueOrDefault() &&
+        !has_top().ValueOrDefault())
+      return false;
+    if (has_top().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_top().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_top().ValueOrDefault() &&
+        has_top().ValueOrDefault() &&
+        !top().Equals(emboss_reserved_local_other.top()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericContainsContainsBitsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_condition().ValueOr(false) &&
+        !has_condition().ValueOr(false))
+      return false;
+    if (has_condition().ValueOr(false) &&
+        !emboss_reserved_local_other.has_condition().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_condition().ValueOr(false) &&
+        has_condition().ValueOr(false) &&
+        !condition().UncheckedEquals(emboss_reserved_local_other.condition()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_top().ValueOr(false) &&
+        !has_top().ValueOr(false))
+      return false;
+    if (has_top().ValueOr(false) &&
+        !emboss_reserved_local_other.has_top().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_top().ValueOr(false) &&
+        has_top().ValueOr(false) &&
+        !top().UncheckedEquals(emboss_reserved_local_other.top()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericContainsContainsBitsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericContainsContainsBitsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericContainsContainsBitsView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "condition") {
+        if (!condition().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "top") {
+        if (!top().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_condition().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          condition().IsAggregate() || condition().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("condition: ");
+        condition().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !condition().IsAggregate() && !condition().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# condition: UNREADABLE\n");
+      }
+    }
+
+    if (has_top().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          top().IsAggregate() || top().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("top: ");
+        top().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !top().IsAggregate() && !top().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# top: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::test::GenericContainsBitsView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ condition() const;
+  ::emboss::support::Maybe<bool> has_condition() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ top() const;
+  ::emboss::support::Maybe<bool> has_top() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericContainsContainsBitsView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.condition().has_top();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_4);
+
+      return emboss_reserved_local_subexpr_5;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericContainsContainsBitsView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericContainsContainsBitsView;
+};
+using ContainsContainsBitsView =
+    GenericContainsContainsBitsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ContainsContainsBitsWriter =
+    GenericContainsContainsBitsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericContainsContainsBitsView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericContainsContainsBitsView<
+    GenericContainsContainsBitsView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericContainsContainsBitsView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeContainsContainsBitsView( T &&emboss_reserved_local_arg) {
+  return GenericContainsContainsBitsView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericContainsContainsBitsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeContainsContainsBitsView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericContainsContainsBitsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericContainsContainsBitsView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedContainsContainsBitsView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericContainsContainsBitsView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace ConditionalInline {
+
+
+
+
+
+namespace Type0 {
+
+}  // namespace Type0
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericType0View;
+
+template <class Storage>
+class GenericType0View final {
+ public:
+  GenericType0View() : backing_() {}
+  explicit GenericType0View(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericType0View(
+      const GenericType0View<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericType0View<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericType0View(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericType0View(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericType0View<Storage> &operator=(
+      const GenericType0View<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_a().Known()) return false;
+    if (has_a().ValueOrDefault() && !a().Ok()) return false;
+
+
+    if (!has_b().Known()) return false;
+    if (has_b().ValueOrDefault() && !b().Ok()) return false;
+
+
+    if (!has_c().Known()) return false;
+    if (has_c().ValueOrDefault() && !c().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericType0View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_a().Known()) return false;
+    if (!emboss_reserved_local_other.has_a().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        !has_a().ValueOrDefault())
+      return false;
+    if (has_a().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        has_a().ValueOrDefault() &&
+        !a().Equals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (!has_b().Known()) return false;
+    if (!emboss_reserved_local_other.has_b().Known()) return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        !has_b().ValueOrDefault())
+      return false;
+    if (has_b().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_b().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        has_b().ValueOrDefault() &&
+        !b().Equals(emboss_reserved_local_other.b()))
+      return false;
+
+
+
+    if (!has_c().Known()) return false;
+    if (!emboss_reserved_local_other.has_c().Known()) return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOrDefault() &&
+        !has_c().ValueOrDefault())
+      return false;
+    if (has_c().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_c().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOrDefault() &&
+        has_c().ValueOrDefault() &&
+        !c().Equals(emboss_reserved_local_other.c()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericType0View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        !has_a().ValueOr(false))
+      return false;
+    if (has_a().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        has_a().ValueOr(false) &&
+        !a().UncheckedEquals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        !has_b().ValueOr(false))
+      return false;
+    if (has_b().ValueOr(false) &&
+        !emboss_reserved_local_other.has_b().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        has_b().ValueOr(false) &&
+        !b().UncheckedEquals(emboss_reserved_local_other.b()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_c().ValueOr(false) &&
+        !has_c().ValueOr(false))
+      return false;
+    if (has_c().ValueOr(false) &&
+        !emboss_reserved_local_other.has_c().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOr(false) &&
+        has_c().ValueOr(false) &&
+        !c().UncheckedEquals(emboss_reserved_local_other.c()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericType0View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericType0View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericType0View<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "a") {
+        if (!a().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "b") {
+        if (!b().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "c") {
+        if (!c().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_a().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a().IsAggregate() || a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a: ");
+        a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a().IsAggregate() && !a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a: UNREADABLE\n");
+      }
+    }
+
+    if (has_b().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b().IsAggregate() || b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("b: ");
+        b().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !b().IsAggregate() && !b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b: UNREADABLE\n");
+      }
+    }
+
+    if (has_c().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          c().IsAggregate() || c().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("c: ");
+        c().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !c().IsAggregate() && !c().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# c: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ a() const;
+  ::emboss::support::Maybe<bool> has_a() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ b() const;
+  ::emboss::support::Maybe<bool> has_b() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ c() const;
+  ::emboss::support::Maybe<bool> has_c() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericType0View;
+};
+using Type0View =
+    GenericType0View</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using Type0Writer =
+    GenericType0View</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericType0View {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericType0View<
+    GenericType0View<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericType0View<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeType0View( T &&emboss_reserved_local_arg) {
+  return GenericType0View<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericType0View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeType0View( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericType0View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericType0View<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedType0View(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericType0View<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+
+namespace Type1 {
+
+}  // namespace Type1
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericType1View;
+
+template <class Storage>
+class GenericType1View final {
+ public:
+  GenericType1View() : backing_() {}
+  explicit GenericType1View(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericType1View(
+      const GenericType1View<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericType1View<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericType1View(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericType1View(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericType1View<Storage> &operator=(
+      const GenericType1View<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_a().Known()) return false;
+    if (has_a().ValueOrDefault() && !a().Ok()) return false;
+
+
+    if (!has_b().Known()) return false;
+    if (has_b().ValueOrDefault() && !b().Ok()) return false;
+
+
+    if (!has_c().Known()) return false;
+    if (has_c().ValueOrDefault() && !c().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericType1View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_a().Known()) return false;
+    if (!emboss_reserved_local_other.has_a().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        !has_a().ValueOrDefault())
+      return false;
+    if (has_a().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        has_a().ValueOrDefault() &&
+        !a().Equals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (!has_b().Known()) return false;
+    if (!emboss_reserved_local_other.has_b().Known()) return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        !has_b().ValueOrDefault())
+      return false;
+    if (has_b().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_b().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        has_b().ValueOrDefault() &&
+        !b().Equals(emboss_reserved_local_other.b()))
+      return false;
+
+
+
+    if (!has_c().Known()) return false;
+    if (!emboss_reserved_local_other.has_c().Known()) return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOrDefault() &&
+        !has_c().ValueOrDefault())
+      return false;
+    if (has_c().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_c().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOrDefault() &&
+        has_c().ValueOrDefault() &&
+        !c().Equals(emboss_reserved_local_other.c()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericType1View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        !has_a().ValueOr(false))
+      return false;
+    if (has_a().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        has_a().ValueOr(false) &&
+        !a().UncheckedEquals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        !has_b().ValueOr(false))
+      return false;
+    if (has_b().ValueOr(false) &&
+        !emboss_reserved_local_other.has_b().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        has_b().ValueOr(false) &&
+        !b().UncheckedEquals(emboss_reserved_local_other.b()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_c().ValueOr(false) &&
+        !has_c().ValueOr(false))
+      return false;
+    if (has_c().ValueOr(false) &&
+        !emboss_reserved_local_other.has_c().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOr(false) &&
+        has_c().ValueOr(false) &&
+        !c().UncheckedEquals(emboss_reserved_local_other.c()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericType1View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericType1View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericType1View<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "a") {
+        if (!a().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "b") {
+        if (!b().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "c") {
+        if (!c().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_a().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a().IsAggregate() || a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a: ");
+        a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a().IsAggregate() && !a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a: UNREADABLE\n");
+      }
+    }
+
+    if (has_b().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b().IsAggregate() || b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("b: ");
+        b().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !b().IsAggregate() && !b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b: UNREADABLE\n");
+      }
+    }
+
+    if (has_c().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          c().IsAggregate() || c().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("c: ");
+        c().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !c().IsAggregate() && !c().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# c: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ a() const;
+  ::emboss::support::Maybe<bool> has_a() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ b() const;
+  ::emboss::support::Maybe<bool> has_b() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ c() const;
+  ::emboss::support::Maybe<bool> has_c() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericType1View;
+};
+using Type1View =
+    GenericType1View</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using Type1Writer =
+    GenericType1View</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericType1View {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericType1View<
+    GenericType1View<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericType1View<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeType1View( T &&emboss_reserved_local_arg) {
+  return GenericType1View<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericType1View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeType1View( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericType1View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericType1View<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedType1View(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericType1View<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+}  // namespace ConditionalInline
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericConditionalInlineView;
+
+template <class Storage>
+class GenericConditionalInlineView final {
+ public:
+  GenericConditionalInlineView() : backing_() {}
+  explicit GenericConditionalInlineView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericConditionalInlineView(
+      const GenericConditionalInlineView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericConditionalInlineView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericConditionalInlineView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericConditionalInlineView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericConditionalInlineView<Storage> &operator=(
+      const GenericConditionalInlineView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_payload_id().Known()) return false;
+    if (has_payload_id().ValueOrDefault() && !payload_id().Ok()) return false;
+
+
+    if (!has_type_0().Known()) return false;
+    if (has_type_0().ValueOrDefault() && !type_0().Ok()) return false;
+
+
+    if (!has_type_1().Known()) return false;
+    if (has_type_1().ValueOrDefault() && !type_1().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericConditionalInlineView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_payload_id().Known()) return false;
+    if (!emboss_reserved_local_other.has_payload_id().Known()) return false;
+
+    if (emboss_reserved_local_other.has_payload_id().ValueOrDefault() &&
+        !has_payload_id().ValueOrDefault())
+      return false;
+    if (has_payload_id().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_payload_id().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_payload_id().ValueOrDefault() &&
+        has_payload_id().ValueOrDefault() &&
+        !payload_id().Equals(emboss_reserved_local_other.payload_id()))
+      return false;
+
+
+
+    if (!has_type_0().Known()) return false;
+    if (!emboss_reserved_local_other.has_type_0().Known()) return false;
+
+    if (emboss_reserved_local_other.has_type_0().ValueOrDefault() &&
+        !has_type_0().ValueOrDefault())
+      return false;
+    if (has_type_0().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_type_0().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_type_0().ValueOrDefault() &&
+        has_type_0().ValueOrDefault() &&
+        !type_0().Equals(emboss_reserved_local_other.type_0()))
+      return false;
+
+
+
+    if (!has_type_1().Known()) return false;
+    if (!emboss_reserved_local_other.has_type_1().Known()) return false;
+
+    if (emboss_reserved_local_other.has_type_1().ValueOrDefault() &&
+        !has_type_1().ValueOrDefault())
+      return false;
+    if (has_type_1().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_type_1().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_type_1().ValueOrDefault() &&
+        has_type_1().ValueOrDefault() &&
+        !type_1().Equals(emboss_reserved_local_other.type_1()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericConditionalInlineView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_payload_id().ValueOr(false) &&
+        !has_payload_id().ValueOr(false))
+      return false;
+    if (has_payload_id().ValueOr(false) &&
+        !emboss_reserved_local_other.has_payload_id().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_payload_id().ValueOr(false) &&
+        has_payload_id().ValueOr(false) &&
+        !payload_id().UncheckedEquals(emboss_reserved_local_other.payload_id()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_type_0().ValueOr(false) &&
+        !has_type_0().ValueOr(false))
+      return false;
+    if (has_type_0().ValueOr(false) &&
+        !emboss_reserved_local_other.has_type_0().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_type_0().ValueOr(false) &&
+        has_type_0().ValueOr(false) &&
+        !type_0().UncheckedEquals(emboss_reserved_local_other.type_0()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_type_1().ValueOr(false) &&
+        !has_type_1().ValueOr(false))
+      return false;
+    if (has_type_1().ValueOr(false) &&
+        !emboss_reserved_local_other.has_type_1().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_type_1().ValueOr(false) &&
+        has_type_1().ValueOr(false) &&
+        !type_1().UncheckedEquals(emboss_reserved_local_other.type_1()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericConditionalInlineView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericConditionalInlineView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericConditionalInlineView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "payload_id") {
+        if (!payload_id().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "type_0") {
+        if (!type_0().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "type_1") {
+        if (!type_1().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_payload_id().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          payload_id().IsAggregate() || payload_id().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("payload_id: ");
+        payload_id().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !payload_id().IsAggregate() && !payload_id().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# payload_id: UNREADABLE\n");
+      }
+    }
+
+    if (has_type_0().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          type_0().IsAggregate() || type_0().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("type_0: ");
+        type_0().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !type_0().IsAggregate() && !type_0().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# type_0: UNREADABLE\n");
+      }
+    }
+
+    if (has_type_1().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          type_1().IsAggregate() || type_1().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("type_1: ");
+        type_1().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !type_1().IsAggregate() && !type_1().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# type_1: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ payload_id() const;
+  ::emboss::support::Maybe<bool> has_payload_id() const;
+
+ public:
+  typename ::emboss::test::ConditionalInline::GenericType0View<typename Storage::template OffsetStorageType</**/0, 1>>
+
+ type_0() const;
+  ::emboss::support::Maybe<bool> has_type_0() const;
+
+ public:
+  typename ::emboss::test::ConditionalInline::GenericType1View<typename Storage::template OffsetStorageType</**/0, 1>>
+
+ type_1() const;
+  ::emboss::support::Maybe<bool> has_type_1() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericConditionalInlineView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.payload_id();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_5, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_4, emboss_reserved_local_subexpr_6);
+
+      return emboss_reserved_local_subexpr_7;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericConditionalInlineView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericConditionalInlineView;
+};
+using ConditionalInlineView =
+    GenericConditionalInlineView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ConditionalInlineWriter =
+    GenericConditionalInlineView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericConditionalInlineView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericConditionalInlineView<
+    GenericConditionalInlineView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericConditionalInlineView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeConditionalInlineView( T &&emboss_reserved_local_arg) {
+  return GenericConditionalInlineView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericConditionalInlineView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeConditionalInlineView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericConditionalInlineView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericConditionalInlineView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedConditionalInlineView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericConditionalInlineView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+
+
+namespace ConditionalAnonymous {
+
+
+
+
+
+namespace EmbossReservedAnonymousField2 {
+
+}  // namespace EmbossReservedAnonymousField2
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField2View;
+
+template <class Storage>
+class GenericEmbossReservedAnonymousField2View final {
+ public:
+  GenericEmbossReservedAnonymousField2View() : backing_() {}
+  explicit GenericEmbossReservedAnonymousField2View(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEmbossReservedAnonymousField2View(
+      const GenericEmbossReservedAnonymousField2View<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericEmbossReservedAnonymousField2View<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericEmbossReservedAnonymousField2View(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericEmbossReservedAnonymousField2View(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEmbossReservedAnonymousField2View<Storage> &operator=(
+      const GenericEmbossReservedAnonymousField2View<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_low().Known()) return false;
+    if (has_low().ValueOrDefault() && !low().Ok()) return false;
+
+
+    if (!has_mid().Known()) return false;
+    if (has_mid().ValueOrDefault() && !mid().Ok()) return false;
+
+
+    if (!has_high().Known()) return false;
+    if (has_high().ValueOrDefault() && !high().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBits().Known()) return false;
+    if (has_IntrinsicSizeInBits().ValueOrDefault() && !IntrinsicSizeInBits().Ok()) return false;
+
+
+    if (!has_MaxSizeInBits().Known()) return false;
+    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok()) return false;
+
+
+    if (!has_MinSizeInBits().Known()) return false;
+    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBits().Ok() &&
+           backing_.SizeInBits() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBits().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBits() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBits().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBits().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericEmbossReservedAnonymousField2View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_low().Known()) return false;
+    if (!emboss_reserved_local_other.has_low().Known()) return false;
+
+    if (emboss_reserved_local_other.has_low().ValueOrDefault() &&
+        !has_low().ValueOrDefault())
+      return false;
+    if (has_low().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_low().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_low().ValueOrDefault() &&
+        has_low().ValueOrDefault() &&
+        !low().Equals(emboss_reserved_local_other.low()))
+      return false;
+
+
+
+    if (!has_mid().Known()) return false;
+    if (!emboss_reserved_local_other.has_mid().Known()) return false;
+
+    if (emboss_reserved_local_other.has_mid().ValueOrDefault() &&
+        !has_mid().ValueOrDefault())
+      return false;
+    if (has_mid().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_mid().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_mid().ValueOrDefault() &&
+        has_mid().ValueOrDefault() &&
+        !mid().Equals(emboss_reserved_local_other.mid()))
+      return false;
+
+
+
+    if (!has_high().Known()) return false;
+    if (!emboss_reserved_local_other.has_high().Known()) return false;
+
+    if (emboss_reserved_local_other.has_high().ValueOrDefault() &&
+        !has_high().ValueOrDefault())
+      return false;
+    if (has_high().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_high().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_high().ValueOrDefault() &&
+        has_high().ValueOrDefault() &&
+        !high().Equals(emboss_reserved_local_other.high()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericEmbossReservedAnonymousField2View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_low().ValueOr(false) &&
+        !has_low().ValueOr(false))
+      return false;
+    if (has_low().ValueOr(false) &&
+        !emboss_reserved_local_other.has_low().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_low().ValueOr(false) &&
+        has_low().ValueOr(false) &&
+        !low().UncheckedEquals(emboss_reserved_local_other.low()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_mid().ValueOr(false) &&
+        !has_mid().ValueOr(false))
+      return false;
+    if (has_mid().ValueOr(false) &&
+        !emboss_reserved_local_other.has_mid().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_mid().ValueOr(false) &&
+        has_mid().ValueOr(false) &&
+        !mid().UncheckedEquals(emboss_reserved_local_other.mid()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_high().ValueOr(false) &&
+        !has_high().ValueOr(false))
+      return false;
+    if (has_high().ValueOr(false) &&
+        !emboss_reserved_local_other.has_high().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_high().ValueOr(false) &&
+        has_high().ValueOr(false) &&
+        !high().UncheckedEquals(emboss_reserved_local_other.high()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericEmbossReservedAnonymousField2View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericEmbossReservedAnonymousField2View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericEmbossReservedAnonymousField2View<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "low") {
+        if (!low().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "mid") {
+        if (!mid().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "high") {
+        if (!high().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_low().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          low().IsAggregate() || low().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("low: ");
+        low().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !low().IsAggregate() && !low().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# low: UNREADABLE\n");
+      }
+    }
+
+    if (has_mid().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          mid().IsAggregate() || mid().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("mid: ");
+        mid().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !mid().IsAggregate() && !mid().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# mid: UNREADABLE\n");
+      }
+    }
+
+    if (has_high().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          high().IsAggregate() || high().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("high: ");
+        high().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !high().IsAggregate() && !high().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# high: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ low() const;
+  ::emboss::support::Maybe<bool> has_low() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<2, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 3>>
+
+ mid() const;
+  ::emboss::support::Maybe<bool> has_mid() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 7>>
+
+ high() const;
+  ::emboss::support::Maybe<bool> has_high() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView IntrinsicSizeInBits() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBitsView() {}
+    EmbossReservedDollarVirtualMaxSizeInBitsView(const EmbossReservedDollarVirtualMaxSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView(EmbossReservedDollarVirtualMaxSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(const EmbossReservedDollarVirtualMaxSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(EmbossReservedDollarVirtualMaxSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBitsView MaxSizeInBits() {
+    return EmbossReservedDollarVirtualMaxSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBitsView() {}
+    EmbossReservedDollarVirtualMinSizeInBitsView(const EmbossReservedDollarVirtualMinSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView(EmbossReservedDollarVirtualMinSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(const EmbossReservedDollarVirtualMinSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(EmbossReservedDollarVirtualMinSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBitsView MinSizeInBits() {
+    return EmbossReservedDollarVirtualMinSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericEmbossReservedAnonymousField2View;
+};
+using EmbossReservedAnonymousField2View =
+    GenericEmbossReservedAnonymousField2View</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using EmbossReservedAnonymousField2Writer =
+    GenericEmbossReservedAnonymousField2View</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField2View {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField2View<
+    GenericEmbossReservedAnonymousField2View<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericEmbossReservedAnonymousField2View<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeEmbossReservedAnonymousField2View( T &&emboss_reserved_local_arg) {
+  return GenericEmbossReservedAnonymousField2View<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericEmbossReservedAnonymousField2View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeEmbossReservedAnonymousField2View( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericEmbossReservedAnonymousField2View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericEmbossReservedAnonymousField2View<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedEmbossReservedAnonymousField2View(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericEmbossReservedAnonymousField2View<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+}  // namespace ConditionalAnonymous
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericConditionalAnonymousView;
+
+template <class Storage>
+class GenericConditionalAnonymousView final {
+ public:
+  GenericConditionalAnonymousView() : backing_() {}
+  explicit GenericConditionalAnonymousView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericConditionalAnonymousView(
+      const GenericConditionalAnonymousView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericConditionalAnonymousView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericConditionalAnonymousView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericConditionalAnonymousView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericConditionalAnonymousView<Storage> &operator=(
+      const GenericConditionalAnonymousView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_emboss_reserved_anonymous_field_2().Known()) return false;
+    if (has_emboss_reserved_anonymous_field_2().ValueOrDefault() && !emboss_reserved_anonymous_field_2().Ok()) return false;
+
+
+    if (!has_low().Known()) return false;
+    if (has_low().ValueOrDefault() && !low().Ok()) return false;
+
+
+    if (!has_mid().Known()) return false;
+    if (has_mid().ValueOrDefault() && !mid().Ok()) return false;
+
+
+    if (!has_high().Known()) return false;
+    if (has_high().ValueOrDefault() && !high().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericConditionalAnonymousView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_emboss_reserved_anonymous_field_2().Known()) return false;
+    if (!emboss_reserved_local_other.has_emboss_reserved_anonymous_field_2().Known()) return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_2().ValueOrDefault() &&
+        !has_emboss_reserved_anonymous_field_2().ValueOrDefault())
+      return false;
+    if (has_emboss_reserved_anonymous_field_2().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_emboss_reserved_anonymous_field_2().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_2().ValueOrDefault() &&
+        has_emboss_reserved_anonymous_field_2().ValueOrDefault() &&
+        !emboss_reserved_anonymous_field_2().Equals(emboss_reserved_local_other.emboss_reserved_anonymous_field_2()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericConditionalAnonymousView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_2().ValueOr(false) &&
+        !has_emboss_reserved_anonymous_field_2().ValueOr(false))
+      return false;
+    if (has_emboss_reserved_anonymous_field_2().ValueOr(false) &&
+        !emboss_reserved_local_other.has_emboss_reserved_anonymous_field_2().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_2().ValueOr(false) &&
+        has_emboss_reserved_anonymous_field_2().ValueOr(false) &&
+        !emboss_reserved_anonymous_field_2().UncheckedEquals(emboss_reserved_local_other.emboss_reserved_anonymous_field_2()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericConditionalAnonymousView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericConditionalAnonymousView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericConditionalAnonymousView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "low") {
+        if (!low().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "mid") {
+        if (!mid().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "high") {
+        if (!high().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_low().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          low().IsAggregate() || low().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("low: ");
+        low().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !low().IsAggregate() && !low().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# low: UNREADABLE\n");
+      }
+    }
+
+    if (has_mid().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          mid().IsAggregate() || mid().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("mid: ");
+        mid().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !mid().IsAggregate() && !mid().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# mid: UNREADABLE\n");
+      }
+    }
+
+    if (has_high().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          high().IsAggregate() || high().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("high: ");
+        high().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !high().IsAggregate() && !high().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# high: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ private:
+  typename ::emboss::test::ConditionalAnonymous::GenericEmbossReservedAnonymousField2View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ emboss_reserved_anonymous_field_2() const;
+  ::emboss::support::Maybe<bool> has_emboss_reserved_anonymous_field_2() const;
+
+ public:
+  auto low() const -> decltype(this->emboss_reserved_anonymous_field_2().low()) {
+   return has_low().ValueOrDefault() ? emboss_reserved_anonymous_field_2().low()
+                                          : decltype(this->emboss_reserved_anonymous_field_2().low())();
+  }
+  ::emboss::support::Maybe<bool> has_low() const;
+
+ public:
+  auto mid() const -> decltype(this->emboss_reserved_anonymous_field_2().mid()) {
+   return has_mid().ValueOrDefault() ? emboss_reserved_anonymous_field_2().mid()
+                                          : decltype(this->emboss_reserved_anonymous_field_2().mid())();
+  }
+  ::emboss::support::Maybe<bool> has_mid() const;
+
+ public:
+  auto high() const -> decltype(this->emboss_reserved_anonymous_field_2().high()) {
+   return has_high().ValueOrDefault() ? emboss_reserved_anonymous_field_2().high()
+                                          : decltype(this->emboss_reserved_anonymous_field_2().high())();
+  }
+  ::emboss::support::Maybe<bool> has_high() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericConditionalAnonymousView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_4);
+
+      return emboss_reserved_local_subexpr_5;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericConditionalAnonymousView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericConditionalAnonymousView;
+};
+using ConditionalAnonymousView =
+    GenericConditionalAnonymousView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ConditionalAnonymousWriter =
+    GenericConditionalAnonymousView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericConditionalAnonymousView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericConditionalAnonymousView<
+    GenericConditionalAnonymousView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericConditionalAnonymousView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeConditionalAnonymousView( T &&emboss_reserved_local_arg) {
+  return GenericConditionalAnonymousView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericConditionalAnonymousView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeConditionalAnonymousView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericConditionalAnonymousView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericConditionalAnonymousView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedConditionalAnonymousView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericConditionalAnonymousView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace ConditionalOnFlag {
+
+
+
+namespace EmbossReservedAnonymousField1 {
+
+}  // namespace EmbossReservedAnonymousField1
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View;
+
+template <class Storage>
+class GenericEmbossReservedAnonymousField1View final {
+ public:
+  GenericEmbossReservedAnonymousField1View() : backing_() {}
+  explicit GenericEmbossReservedAnonymousField1View(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEmbossReservedAnonymousField1View(
+      const GenericEmbossReservedAnonymousField1View<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericEmbossReservedAnonymousField1View(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericEmbossReservedAnonymousField1View(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEmbossReservedAnonymousField1View<Storage> &operator=(
+      const GenericEmbossReservedAnonymousField1View<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_enabled().Known()) return false;
+    if (has_enabled().ValueOrDefault() && !enabled().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBits().Known()) return false;
+    if (has_IntrinsicSizeInBits().ValueOrDefault() && !IntrinsicSizeInBits().Ok()) return false;
+
+
+    if (!has_MaxSizeInBits().Known()) return false;
+    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok()) return false;
+
+
+    if (!has_MinSizeInBits().Known()) return false;
+    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBits().Ok() &&
+           backing_.SizeInBits() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBits().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBits() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBits().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBits().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_enabled().Known()) return false;
+    if (!emboss_reserved_local_other.has_enabled().Known()) return false;
+
+    if (emboss_reserved_local_other.has_enabled().ValueOrDefault() &&
+        !has_enabled().ValueOrDefault())
+      return false;
+    if (has_enabled().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_enabled().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_enabled().ValueOrDefault() &&
+        has_enabled().ValueOrDefault() &&
+        !enabled().Equals(emboss_reserved_local_other.enabled()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_enabled().ValueOr(false) &&
+        !has_enabled().ValueOr(false))
+      return false;
+    if (has_enabled().ValueOr(false) &&
+        !emboss_reserved_local_other.has_enabled().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_enabled().ValueOr(false) &&
+        has_enabled().ValueOr(false) &&
+        !enabled().UncheckedEquals(emboss_reserved_local_other.enabled()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "enabled") {
+        if (!enabled().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_enabled().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          enabled().IsAggregate() || enabled().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("enabled: ");
+        enabled().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !enabled().IsAggregate() && !enabled().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# enabled: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ enabled() const;
+  ::emboss::support::Maybe<bool> has_enabled() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView IntrinsicSizeInBits() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBitsView() {}
+    EmbossReservedDollarVirtualMaxSizeInBitsView(const EmbossReservedDollarVirtualMaxSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView(EmbossReservedDollarVirtualMaxSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(const EmbossReservedDollarVirtualMaxSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(EmbossReservedDollarVirtualMaxSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBitsView MaxSizeInBits() {
+    return EmbossReservedDollarVirtualMaxSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBitsView() {}
+    EmbossReservedDollarVirtualMinSizeInBitsView(const EmbossReservedDollarVirtualMinSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView(EmbossReservedDollarVirtualMinSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(const EmbossReservedDollarVirtualMinSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(EmbossReservedDollarVirtualMinSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBitsView MinSizeInBits() {
+    return EmbossReservedDollarVirtualMinSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericEmbossReservedAnonymousField1View;
+};
+using EmbossReservedAnonymousField1View =
+    GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using EmbossReservedAnonymousField1Writer =
+    GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View<
+    GenericEmbossReservedAnonymousField1View<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericEmbossReservedAnonymousField1View<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeEmbossReservedAnonymousField1View( T &&emboss_reserved_local_arg) {
+  return GenericEmbossReservedAnonymousField1View<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeEmbossReservedAnonymousField1View( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericEmbossReservedAnonymousField1View<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedEmbossReservedAnonymousField1View(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericEmbossReservedAnonymousField1View<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+}  // namespace ConditionalOnFlag
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericConditionalOnFlagView;
+
+template <class Storage>
+class GenericConditionalOnFlagView final {
+ public:
+  GenericConditionalOnFlagView() : backing_() {}
+  explicit GenericConditionalOnFlagView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericConditionalOnFlagView(
+      const GenericConditionalOnFlagView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericConditionalOnFlagView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericConditionalOnFlagView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericConditionalOnFlagView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericConditionalOnFlagView<Storage> &operator=(
+      const GenericConditionalOnFlagView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_emboss_reserved_anonymous_field_1().Known()) return false;
+    if (has_emboss_reserved_anonymous_field_1().ValueOrDefault() && !emboss_reserved_anonymous_field_1().Ok()) return false;
+
+
+    if (!has_enabled().Known()) return false;
+    if (has_enabled().ValueOrDefault() && !enabled().Ok()) return false;
+
+
+    if (!has_value().Known()) return false;
+    if (has_value().ValueOrDefault() && !value().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericConditionalOnFlagView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_emboss_reserved_anonymous_field_1().Known()) return false;
+    if (!emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().Known()) return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        !has_emboss_reserved_anonymous_field_1().ValueOrDefault())
+      return false;
+    if (has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        !emboss_reserved_anonymous_field_1().Equals(emboss_reserved_local_other.emboss_reserved_anonymous_field_1()))
+      return false;
+
+
+
+    if (!has_value().Known()) return false;
+    if (!emboss_reserved_local_other.has_value().Known()) return false;
+
+    if (emboss_reserved_local_other.has_value().ValueOrDefault() &&
+        !has_value().ValueOrDefault())
+      return false;
+    if (has_value().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_value().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_value().ValueOrDefault() &&
+        has_value().ValueOrDefault() &&
+        !value().Equals(emboss_reserved_local_other.value()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericConditionalOnFlagView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        !has_emboss_reserved_anonymous_field_1().ValueOr(false))
+      return false;
+    if (has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        !emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        !emboss_reserved_anonymous_field_1().UncheckedEquals(emboss_reserved_local_other.emboss_reserved_anonymous_field_1()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_value().ValueOr(false) &&
+        !has_value().ValueOr(false))
+      return false;
+    if (has_value().ValueOr(false) &&
+        !emboss_reserved_local_other.has_value().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_value().ValueOr(false) &&
+        has_value().ValueOr(false) &&
+        !value().UncheckedEquals(emboss_reserved_local_other.value()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericConditionalOnFlagView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericConditionalOnFlagView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericConditionalOnFlagView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "enabled") {
+        if (!enabled().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "value") {
+        if (!value().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_enabled().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          enabled().IsAggregate() || enabled().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("enabled: ");
+        enabled().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !enabled().IsAggregate() && !enabled().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# enabled: UNREADABLE\n");
+      }
+    }
+
+    if (has_value().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          value().IsAggregate() || value().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("value: ");
+        value().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !value().IsAggregate() && !value().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# value: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ private:
+  typename ::emboss::test::ConditionalOnFlag::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ emboss_reserved_anonymous_field_1() const;
+  ::emboss::support::Maybe<bool> has_emboss_reserved_anonymous_field_1() const;
+
+ public:
+  auto enabled() const -> decltype(this->emboss_reserved_anonymous_field_1().enabled()) {
+   return has_enabled().ValueOrDefault() ? emboss_reserved_anonymous_field_1().enabled()
+                                          : decltype(this->emboss_reserved_anonymous_field_1().enabled())();
+  }
+  ::emboss::support::Maybe<bool> has_enabled() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ value() const;
+  ::emboss::support::Maybe<bool> has_value() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericConditionalOnFlagView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.enabled();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/bool>(static_cast</**/bool>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/bool>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_3);
+
+      return emboss_reserved_local_subexpr_4;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericConditionalOnFlagView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericConditionalOnFlagView;
+};
+using ConditionalOnFlagView =
+    GenericConditionalOnFlagView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ConditionalOnFlagWriter =
+    GenericConditionalOnFlagView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericConditionalOnFlagView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericConditionalOnFlagView<
+    GenericConditionalOnFlagView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericConditionalOnFlagView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeConditionalOnFlagView( T &&emboss_reserved_local_arg) {
+  return GenericConditionalOnFlagView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericConditionalOnFlagView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeConditionalOnFlagView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericConditionalOnFlagView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericConditionalOnFlagView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedConditionalOnFlagView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericConditionalOnFlagView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace BasicConditional {
+
+}  // namespace BasicConditional
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericBasicConditionalView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBasicConditionalView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericBasicConditionalView<Storage>::xc()
+    const {
+
+  if ( has_xc().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBasicConditionalView<Storage>::has_xc() const {
+  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+}
+
+
+template <class Storage>
+inline typename GenericBasicConditionalView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericBasicConditionalView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericBasicConditionalView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBasicConditionalView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace BasicConditional {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace BasicConditional
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBasicConditionalView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return BasicConditional::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBasicConditionalView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return BasicConditional::MaxSizeInBytes();
+}
+
+namespace BasicConditional {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace BasicConditional
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBasicConditionalView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return BasicConditional::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBasicConditionalView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return BasicConditional::MinSizeInBytes();
+}
+namespace NegativeConditional {
+
+}  // namespace NegativeConditional
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericNegativeConditionalView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNegativeConditionalView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericNegativeConditionalView<Storage>::xc()
+    const {
+
+  if ( has_xc().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNegativeConditionalView<Storage>::has_xc() const {
+  return ::emboss::support::NotEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+}
+
+
+template <class Storage>
+inline typename GenericNegativeConditionalView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericNegativeConditionalView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericNegativeConditionalView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNegativeConditionalView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace NegativeConditional {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace NegativeConditional
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericNegativeConditionalView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return NegativeConditional::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericNegativeConditionalView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return NegativeConditional::MaxSizeInBytes();
+}
+
+namespace NegativeConditional {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace NegativeConditional
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericNegativeConditionalView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return NegativeConditional::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericNegativeConditionalView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return NegativeConditional::MinSizeInBytes();
+}
+namespace ConditionalAndUnconditionalOverlappingFinalField {
+
+}  // namespace ConditionalAndUnconditionalOverlappingFinalField
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericConditionalAndUnconditionalOverlappingFinalFieldView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionalAndUnconditionalOverlappingFinalFieldView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericConditionalAndUnconditionalOverlappingFinalFieldView<Storage>::xc()
+    const {
+
+  if ( has_xc().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionalAndUnconditionalOverlappingFinalFieldView<Storage>::has_xc() const {
+  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericConditionalAndUnconditionalOverlappingFinalFieldView<Storage>::z()
+    const {
+
+  if ( has_z().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionalAndUnconditionalOverlappingFinalFieldView<Storage>::has_z() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace ConditionalAndUnconditionalOverlappingFinalField {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace ConditionalAndUnconditionalOverlappingFinalField
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalAndUnconditionalOverlappingFinalFieldView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return ConditionalAndUnconditionalOverlappingFinalField::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalAndUnconditionalOverlappingFinalFieldView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return ConditionalAndUnconditionalOverlappingFinalField::IntrinsicSizeInBytes();
+}
+
+namespace ConditionalAndUnconditionalOverlappingFinalField {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace ConditionalAndUnconditionalOverlappingFinalField
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalAndUnconditionalOverlappingFinalFieldView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return ConditionalAndUnconditionalOverlappingFinalField::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalAndUnconditionalOverlappingFinalFieldView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return ConditionalAndUnconditionalOverlappingFinalField::MaxSizeInBytes();
+}
+
+namespace ConditionalAndUnconditionalOverlappingFinalField {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace ConditionalAndUnconditionalOverlappingFinalField
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalAndUnconditionalOverlappingFinalFieldView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return ConditionalAndUnconditionalOverlappingFinalField::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalAndUnconditionalOverlappingFinalFieldView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return ConditionalAndUnconditionalOverlappingFinalField::MinSizeInBytes();
+}
+namespace ConditionalBasicConditionalFieldFirst {
+
+}  // namespace ConditionalBasicConditionalFieldFirst
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericConditionalBasicConditionalFieldFirstView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionalBasicConditionalFieldFirstView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericConditionalBasicConditionalFieldFirstView<Storage>::xc()
+    const {
+
+  if ( has_xc().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionalBasicConditionalFieldFirstView<Storage>::has_xc() const {
+  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+}
+
+
+namespace ConditionalBasicConditionalFieldFirst {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace ConditionalBasicConditionalFieldFirst
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalBasicConditionalFieldFirstView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return ConditionalBasicConditionalFieldFirst::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalBasicConditionalFieldFirstView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return ConditionalBasicConditionalFieldFirst::IntrinsicSizeInBytes();
+}
+
+namespace ConditionalBasicConditionalFieldFirst {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace ConditionalBasicConditionalFieldFirst
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalBasicConditionalFieldFirstView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return ConditionalBasicConditionalFieldFirst::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalBasicConditionalFieldFirstView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return ConditionalBasicConditionalFieldFirst::MaxSizeInBytes();
+}
+
+namespace ConditionalBasicConditionalFieldFirst {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace ConditionalBasicConditionalFieldFirst
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalBasicConditionalFieldFirstView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return ConditionalBasicConditionalFieldFirst::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalBasicConditionalFieldFirstView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return ConditionalBasicConditionalFieldFirst::MinSizeInBytes();
+}
+namespace ConditionalAndDynamicLocation {
+
+}  // namespace ConditionalAndDynamicLocation
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericConditionalAndDynamicLocationView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionalAndDynamicLocationView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ GenericConditionalAndDynamicLocationView<Storage>::y()
+    const {
+
+  if ( has_y().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionalAndDynamicLocationView<Storage>::has_y() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+ GenericConditionalAndDynamicLocationView<Storage>::xc()
+    const {
+
+  if ( has_xc().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = y();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_2;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionalAndDynamicLocationView<Storage>::has_xc() const {
+  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+}
+
+
+template <class Storage>
+inline typename GenericConditionalAndDynamicLocationView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericConditionalAndDynamicLocationView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericConditionalAndDynamicLocationView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionalAndDynamicLocationView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace ConditionalAndDynamicLocation {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(256LL)).ValueOrDefault();
+}
+}  // namespace ConditionalAndDynamicLocation
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalAndDynamicLocationView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return ConditionalAndDynamicLocation::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalAndDynamicLocationView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return ConditionalAndDynamicLocation::MaxSizeInBytes();
+}
+
+namespace ConditionalAndDynamicLocation {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace ConditionalAndDynamicLocation
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalAndDynamicLocationView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return ConditionalAndDynamicLocation::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalAndDynamicLocationView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return ConditionalAndDynamicLocation::MinSizeInBytes();
+}
+namespace ConditionUsesMinInt {
+
+}  // namespace ConditionUsesMinInt
+
+
+template <class Storage>
+inline typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericConditionUsesMinIntView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionUsesMinIntView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericConditionUsesMinIntView<Storage>::xc()
+    const {
+
+  if ( has_xc().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionUsesMinIntView<Storage>::has_xc() const {
+  return ::emboss::support::Equal</**/::std::int64_t, bool, ::std::int64_t, ::std::int64_t>(::emboss::support::Difference</**/::std::int64_t, ::std::int64_t, ::std::int32_t, ::std::int64_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int64_t>(static_cast</**/::std::int64_t>(9223372036854775680LL))), ::emboss::support::Maybe</**/::std::int64_t>(static_cast</**/::std::int64_t>(-9223372036854775807LL - 1)));
+}
+
+
+template <class Storage>
+inline typename GenericConditionUsesMinIntView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericConditionUsesMinIntView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericConditionUsesMinIntView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionUsesMinIntView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace ConditionUsesMinInt {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace ConditionUsesMinInt
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionUsesMinIntView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return ConditionUsesMinInt::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionUsesMinIntView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return ConditionUsesMinInt::MaxSizeInBytes();
+}
+
+namespace ConditionUsesMinInt {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace ConditionUsesMinInt
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionUsesMinIntView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return ConditionUsesMinInt::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionUsesMinIntView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return ConditionUsesMinInt::MinSizeInBytes();
+}
+namespace NestedConditional {
+
+}  // namespace NestedConditional
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericNestedConditionalView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNestedConditionalView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericNestedConditionalView<Storage>::xc()
+    const {
+
+  if ( has_xc().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNestedConditionalView<Storage>::has_xc() const {
+  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ GenericNestedConditionalView<Storage>::xcc()
+    const {
+
+  if ( has_xcc().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNestedConditionalView<Storage>::has_xcc() const {
+  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((xc().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(xc().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+}
+
+
+template <class Storage>
+inline typename GenericNestedConditionalView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericNestedConditionalView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericNestedConditionalView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNestedConditionalView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace NestedConditional {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace NestedConditional
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericNestedConditionalView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return NestedConditional::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericNestedConditionalView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return NestedConditional::MaxSizeInBytes();
+}
+
+namespace NestedConditional {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace NestedConditional
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericNestedConditionalView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return NestedConditional::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericNestedConditionalView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return NestedConditional::MinSizeInBytes();
+}
+namespace CorrectNestedConditional {
+
+}  // namespace CorrectNestedConditional
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericCorrectNestedConditionalView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericCorrectNestedConditionalView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericCorrectNestedConditionalView<Storage>::xc()
+    const {
+
+  if ( has_xc().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericCorrectNestedConditionalView<Storage>::has_xc() const {
+  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ GenericCorrectNestedConditionalView<Storage>::xcc()
+    const {
+
+  if ( has_xcc().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericCorrectNestedConditionalView<Storage>::has_xcc() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL))), ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((xc().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(xc().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL))));
+}
+
+
+template <class Storage>
+inline typename GenericCorrectNestedConditionalView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericCorrectNestedConditionalView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericCorrectNestedConditionalView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericCorrectNestedConditionalView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace CorrectNestedConditional {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace CorrectNestedConditional
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericCorrectNestedConditionalView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return CorrectNestedConditional::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericCorrectNestedConditionalView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return CorrectNestedConditional::MaxSizeInBytes();
+}
+
+namespace CorrectNestedConditional {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace CorrectNestedConditional
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericCorrectNestedConditionalView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return CorrectNestedConditional::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericCorrectNestedConditionalView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return CorrectNestedConditional::MinSizeInBytes();
+}
+namespace AlwaysFalseCondition {
+
+}  // namespace AlwaysFalseCondition
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericAlwaysFalseConditionView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAlwaysFalseConditionView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericAlwaysFalseConditionView<Storage>::xc()
+    const {
+
+  if ( has_xc().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAlwaysFalseConditionView<Storage>::has_xc() const {
+  return ::emboss::support::Maybe</**/bool>(false);
+}
+
+
+namespace AlwaysFalseCondition {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace AlwaysFalseCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAlwaysFalseConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return AlwaysFalseCondition::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAlwaysFalseConditionView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return AlwaysFalseCondition::IntrinsicSizeInBytes();
+}
+
+namespace AlwaysFalseCondition {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace AlwaysFalseCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAlwaysFalseConditionView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return AlwaysFalseCondition::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAlwaysFalseConditionView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return AlwaysFalseCondition::MaxSizeInBytes();
+}
+
+namespace AlwaysFalseCondition {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace AlwaysFalseCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAlwaysFalseConditionView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return AlwaysFalseCondition::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAlwaysFalseConditionView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return AlwaysFalseCondition::MinSizeInBytes();
+}
+namespace OnlyAlwaysFalseCondition {
+
+}  // namespace OnlyAlwaysFalseCondition
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericOnlyAlwaysFalseConditionView<Storage>::xc()
+    const {
+
+  if ( has_xc().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericOnlyAlwaysFalseConditionView<Storage>::has_xc() const {
+  return ::emboss::support::Maybe</**/bool>(false);
+}
+
+
+namespace OnlyAlwaysFalseCondition {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)).ValueOrDefault();
+}
+}  // namespace OnlyAlwaysFalseCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOnlyAlwaysFalseConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return OnlyAlwaysFalseCondition::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOnlyAlwaysFalseConditionView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return OnlyAlwaysFalseCondition::IntrinsicSizeInBytes();
+}
+
+namespace OnlyAlwaysFalseCondition {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)).ValueOrDefault();
+}
+}  // namespace OnlyAlwaysFalseCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOnlyAlwaysFalseConditionView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return OnlyAlwaysFalseCondition::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOnlyAlwaysFalseConditionView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return OnlyAlwaysFalseCondition::MaxSizeInBytes();
+}
+
+namespace OnlyAlwaysFalseCondition {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)).ValueOrDefault();
+}
+}  // namespace OnlyAlwaysFalseCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOnlyAlwaysFalseConditionView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return OnlyAlwaysFalseCondition::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOnlyAlwaysFalseConditionView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return OnlyAlwaysFalseCondition::MinSizeInBytes();
+}
+namespace EmptyStruct {
+
+}  // namespace EmptyStruct
+
+
+namespace EmptyStruct {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)).ValueOrDefault();
+}
+}  // namespace EmptyStruct
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmptyStructView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return EmptyStruct::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmptyStructView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return EmptyStruct::IntrinsicSizeInBytes();
+}
+
+namespace EmptyStruct {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)).ValueOrDefault();
+}
+}  // namespace EmptyStruct
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmptyStructView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return EmptyStruct::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmptyStructView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return EmptyStruct::MaxSizeInBytes();
+}
+
+namespace EmptyStruct {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)).ValueOrDefault();
+}
+}  // namespace EmptyStruct
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmptyStructView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return EmptyStruct::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmptyStructView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return EmptyStruct::MinSizeInBytes();
+}
+namespace AlwaysFalseConditionDynamicSize {
+
+}  // namespace AlwaysFalseConditionDynamicSize
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericAlwaysFalseConditionDynamicSizeView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAlwaysFalseConditionDynamicSizeView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+ GenericAlwaysFalseConditionDynamicSizeView<Storage>::y()
+    const {
+
+  if ( has_y().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = x();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_2;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAlwaysFalseConditionDynamicSizeView<Storage>::has_y() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericAlwaysFalseConditionDynamicSizeView<Storage>::xc()
+    const {
+
+  if ( has_xc().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAlwaysFalseConditionDynamicSizeView<Storage>::has_xc() const {
+  return ::emboss::support::Maybe</**/bool>(false);
+}
+
+
+template <class Storage>
+inline typename GenericAlwaysFalseConditionDynamicSizeView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericAlwaysFalseConditionDynamicSizeView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericAlwaysFalseConditionDynamicSizeView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAlwaysFalseConditionDynamicSizeView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace AlwaysFalseConditionDynamicSize {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(256LL)).ValueOrDefault();
+}
+}  // namespace AlwaysFalseConditionDynamicSize
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAlwaysFalseConditionDynamicSizeView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return AlwaysFalseConditionDynamicSize::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAlwaysFalseConditionDynamicSizeView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return AlwaysFalseConditionDynamicSize::MaxSizeInBytes();
+}
+
+namespace AlwaysFalseConditionDynamicSize {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace AlwaysFalseConditionDynamicSize
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAlwaysFalseConditionDynamicSizeView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return AlwaysFalseConditionDynamicSize::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAlwaysFalseConditionDynamicSizeView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return AlwaysFalseConditionDynamicSize::MinSizeInBytes();
+}
+namespace ConditionDoesNotContributeToSize {
+
+}  // namespace ConditionDoesNotContributeToSize
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericConditionDoesNotContributeToSizeView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionDoesNotContributeToSizeView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericConditionDoesNotContributeToSizeView<Storage>::xc()
+    const {
+
+  if ( has_xc().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionDoesNotContributeToSizeView<Storage>::has_xc() const {
+  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ GenericConditionDoesNotContributeToSizeView<Storage>::y()
+    const {
+
+  if ( has_y().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionDoesNotContributeToSizeView<Storage>::has_y() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace ConditionDoesNotContributeToSize {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace ConditionDoesNotContributeToSize
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionDoesNotContributeToSizeView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return ConditionDoesNotContributeToSize::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionDoesNotContributeToSizeView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return ConditionDoesNotContributeToSize::IntrinsicSizeInBytes();
+}
+
+namespace ConditionDoesNotContributeToSize {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace ConditionDoesNotContributeToSize
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionDoesNotContributeToSizeView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return ConditionDoesNotContributeToSize::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionDoesNotContributeToSizeView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return ConditionDoesNotContributeToSize::MaxSizeInBytes();
+}
+
+namespace ConditionDoesNotContributeToSize {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace ConditionDoesNotContributeToSize
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionDoesNotContributeToSizeView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return ConditionDoesNotContributeToSize::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionDoesNotContributeToSizeView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return ConditionDoesNotContributeToSize::MinSizeInBytes();
+}
+namespace EnumCondition {
+
+}  // namespace EnumCondition
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::OnOff,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericEnumConditionView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::OnOff,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::OnOff,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEnumConditionView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericEnumConditionView<Storage>::xc()
+    const {
+
+  if ( has_xc().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEnumConditionView<Storage>::has_xc() const {
+  return ::emboss::support::Equal</**/::emboss::test::OnOff, bool, ::emboss::test::OnOff, ::emboss::test::OnOff>((x().Ok()    ? ::emboss::support::Maybe</**/::emboss::test::OnOff>(static_cast</**/::emboss::test::OnOff>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::OnOff>()), ::emboss::support::Maybe</**/::emboss::test::OnOff>(static_cast</**/::emboss::test::OnOff>(1)));
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericEnumConditionView<Storage>::xc2()
+    const {
+
+  if ( has_xc2().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEnumConditionView<Storage>::has_xc2() const {
+  return ::emboss::support::GreaterThan</**/::emboss::test::OnOff, bool, ::emboss::test::OnOff, ::emboss::test::OnOff>((x().Ok()    ? ::emboss::support::Maybe</**/::emboss::test::OnOff>(static_cast</**/::emboss::test::OnOff>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::OnOff>()), ::emboss::support::Maybe</**/::emboss::test::OnOff>(static_cast</**/::emboss::test::OnOff>(0)));
+}
+
+
+template <class Storage>
+inline typename GenericEnumConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericEnumConditionView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericEnumConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEnumConditionView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace EnumCondition {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace EnumCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEnumConditionView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return EnumCondition::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEnumConditionView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return EnumCondition::MaxSizeInBytes();
+}
+
+namespace EnumCondition {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace EnumCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEnumConditionView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return EnumCondition::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEnumConditionView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return EnumCondition::MinSizeInBytes();
+}
+namespace NegativeEnumCondition {
+
+}  // namespace NegativeEnumCondition
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::OnOff,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericNegativeEnumConditionView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::OnOff,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::OnOff,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNegativeEnumConditionView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericNegativeEnumConditionView<Storage>::xc()
+    const {
+
+  if ( has_xc().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNegativeEnumConditionView<Storage>::has_xc() const {
+  return ::emboss::support::NotEqual</**/::emboss::test::OnOff, bool, ::emboss::test::OnOff, ::emboss::test::OnOff>((x().Ok()    ? ::emboss::support::Maybe</**/::emboss::test::OnOff>(static_cast</**/::emboss::test::OnOff>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::OnOff>()), ::emboss::support::Maybe</**/::emboss::test::OnOff>(static_cast</**/::emboss::test::OnOff>(1)));
+}
+
+
+template <class Storage>
+inline typename GenericNegativeEnumConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericNegativeEnumConditionView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericNegativeEnumConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNegativeEnumConditionView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace NegativeEnumCondition {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace NegativeEnumCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericNegativeEnumConditionView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return NegativeEnumCondition::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericNegativeEnumConditionView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return NegativeEnumCondition::MaxSizeInBytes();
+}
+
+namespace NegativeEnumCondition {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace NegativeEnumCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericNegativeEnumConditionView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return NegativeEnumCondition::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericNegativeEnumConditionView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return NegativeEnumCondition::MinSizeInBytes();
+}
+namespace LessThanCondition {
+
+}  // namespace LessThanCondition
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericLessThanConditionView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericLessThanConditionView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericLessThanConditionView<Storage>::xc()
+    const {
+
+  if ( has_xc().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericLessThanConditionView<Storage>::has_xc() const {
+  return ::emboss::support::LessThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
+}
+
+
+template <class Storage>
+inline typename GenericLessThanConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericLessThanConditionView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericLessThanConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericLessThanConditionView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace LessThanCondition {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace LessThanCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericLessThanConditionView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return LessThanCondition::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericLessThanConditionView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return LessThanCondition::MaxSizeInBytes();
+}
+
+namespace LessThanCondition {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace LessThanCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericLessThanConditionView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return LessThanCondition::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericLessThanConditionView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return LessThanCondition::MinSizeInBytes();
+}
+namespace LessThanOrEqualCondition {
+
+}  // namespace LessThanOrEqualCondition
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericLessThanOrEqualConditionView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericLessThanOrEqualConditionView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericLessThanOrEqualConditionView<Storage>::xc()
+    const {
+
+  if ( has_xc().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericLessThanOrEqualConditionView<Storage>::has_xc() const {
+  return ::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
+}
+
+
+template <class Storage>
+inline typename GenericLessThanOrEqualConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericLessThanOrEqualConditionView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericLessThanOrEqualConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericLessThanOrEqualConditionView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace LessThanOrEqualCondition {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace LessThanOrEqualCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericLessThanOrEqualConditionView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return LessThanOrEqualCondition::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericLessThanOrEqualConditionView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return LessThanOrEqualCondition::MaxSizeInBytes();
+}
+
+namespace LessThanOrEqualCondition {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace LessThanOrEqualCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericLessThanOrEqualConditionView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return LessThanOrEqualCondition::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericLessThanOrEqualConditionView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return LessThanOrEqualCondition::MinSizeInBytes();
+}
+namespace GreaterThanOrEqualCondition {
+
+}  // namespace GreaterThanOrEqualCondition
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericGreaterThanOrEqualConditionView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericGreaterThanOrEqualConditionView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericGreaterThanOrEqualConditionView<Storage>::xc()
+    const {
+
+  if ( has_xc().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericGreaterThanOrEqualConditionView<Storage>::has_xc() const {
+  return ::emboss::support::GreaterThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
+}
+
+
+template <class Storage>
+inline typename GenericGreaterThanOrEqualConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericGreaterThanOrEqualConditionView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericGreaterThanOrEqualConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericGreaterThanOrEqualConditionView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace GreaterThanOrEqualCondition {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace GreaterThanOrEqualCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericGreaterThanOrEqualConditionView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return GreaterThanOrEqualCondition::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericGreaterThanOrEqualConditionView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return GreaterThanOrEqualCondition::MaxSizeInBytes();
+}
+
+namespace GreaterThanOrEqualCondition {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace GreaterThanOrEqualCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericGreaterThanOrEqualConditionView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return GreaterThanOrEqualCondition::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericGreaterThanOrEqualConditionView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return GreaterThanOrEqualCondition::MinSizeInBytes();
+}
+namespace GreaterThanCondition {
+
+}  // namespace GreaterThanCondition
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericGreaterThanConditionView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericGreaterThanConditionView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericGreaterThanConditionView<Storage>::xc()
+    const {
+
+  if ( has_xc().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericGreaterThanConditionView<Storage>::has_xc() const {
+  return ::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
+}
+
+
+template <class Storage>
+inline typename GenericGreaterThanConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericGreaterThanConditionView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericGreaterThanConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericGreaterThanConditionView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace GreaterThanCondition {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace GreaterThanCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericGreaterThanConditionView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return GreaterThanCondition::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericGreaterThanConditionView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return GreaterThanCondition::MaxSizeInBytes();
+}
+
+namespace GreaterThanCondition {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace GreaterThanCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericGreaterThanConditionView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return GreaterThanCondition::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericGreaterThanConditionView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return GreaterThanCondition::MinSizeInBytes();
+}
+namespace RangeCondition {
+
+}  // namespace RangeCondition
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericRangeConditionView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRangeConditionView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericRangeConditionView<Storage>::y()
+    const {
+
+  if ( has_y().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRangeConditionView<Storage>::has_y() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ GenericRangeConditionView<Storage>::xc()
+    const {
+
+  if ( has_xc().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRangeConditionView<Storage>::has_xc() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::LessThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)), (x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>())), ::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), (y().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(y().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()))), ::emboss::support::LessThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((y().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(y().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL))));
+}
+
+
+template <class Storage>
+inline typename GenericRangeConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericRangeConditionView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericRangeConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRangeConditionView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace RangeCondition {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace RangeCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRangeConditionView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return RangeCondition::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRangeConditionView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return RangeCondition::MaxSizeInBytes();
+}
+
+namespace RangeCondition {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace RangeCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRangeConditionView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return RangeCondition::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRangeConditionView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return RangeCondition::MinSizeInBytes();
+}
+namespace ReverseRangeCondition {
+
+}  // namespace ReverseRangeCondition
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericReverseRangeConditionView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericReverseRangeConditionView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericReverseRangeConditionView<Storage>::y()
+    const {
+
+  if ( has_y().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericReverseRangeConditionView<Storage>::has_y() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ GenericReverseRangeConditionView<Storage>::xc()
+    const {
+
+  if ( has_xc().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericReverseRangeConditionView<Storage>::has_xc() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)), (y().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(y().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>())), ::emboss::support::GreaterThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((y().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(y().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), (x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()))), ::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL))));
+}
+
+
+template <class Storage>
+inline typename GenericReverseRangeConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericReverseRangeConditionView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericReverseRangeConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericReverseRangeConditionView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace ReverseRangeCondition {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace ReverseRangeCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericReverseRangeConditionView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return ReverseRangeCondition::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericReverseRangeConditionView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return ReverseRangeCondition::MaxSizeInBytes();
+}
+
+namespace ReverseRangeCondition {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace ReverseRangeCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericReverseRangeConditionView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return ReverseRangeCondition::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericReverseRangeConditionView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return ReverseRangeCondition::MinSizeInBytes();
+}
+namespace AndCondition {
+
+}  // namespace AndCondition
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericAndConditionView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAndConditionView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericAndConditionView<Storage>::y()
+    const {
+
+  if ( has_y().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAndConditionView<Storage>::has_y() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ GenericAndConditionView<Storage>::xc()
+    const {
+
+  if ( has_xc().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAndConditionView<Storage>::has_xc() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL))), ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((y().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(y().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL))));
+}
+
+
+template <class Storage>
+inline typename GenericAndConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericAndConditionView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericAndConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAndConditionView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace AndCondition {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace AndCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAndConditionView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return AndCondition::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAndConditionView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return AndCondition::MaxSizeInBytes();
+}
+
+namespace AndCondition {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace AndCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAndConditionView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return AndCondition::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAndConditionView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return AndCondition::MinSizeInBytes();
+}
+namespace OrCondition {
+
+}  // namespace OrCondition
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericOrConditionView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericOrConditionView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericOrConditionView<Storage>::y()
+    const {
+
+  if ( has_y().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericOrConditionView<Storage>::has_y() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ GenericOrConditionView<Storage>::xc()
+    const {
+
+  if ( has_xc().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericOrConditionView<Storage>::has_xc() const {
+  return ::emboss::support::Or</**/bool, bool, bool, bool>(::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL))), ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((y().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(y().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL))));
+}
+
+
+template <class Storage>
+inline typename GenericOrConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericOrConditionView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericOrConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericOrConditionView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace OrCondition {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace OrCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOrConditionView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return OrCondition::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOrConditionView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return OrCondition::MaxSizeInBytes();
+}
+
+namespace OrCondition {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace OrCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOrConditionView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return OrCondition::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOrConditionView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return OrCondition::MinSizeInBytes();
+}
+namespace ChoiceCondition {
+
+}  // namespace ChoiceCondition
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::ChoiceCondition::Field,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericChoiceConditionView<Storage>::field()
+    const {
+
+  if ( has_field().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::ChoiceCondition::Field,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::ChoiceCondition::Field,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericChoiceConditionView<Storage>::has_field() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericChoiceConditionView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericChoiceConditionView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ GenericChoiceConditionView<Storage>::y()
+    const {
+
+  if ( has_y().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericChoiceConditionView<Storage>::has_y() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 8>>
+
+ GenericChoiceConditionView<Storage>::xyc()
+    const {
+
+  if ( has_xyc().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   3>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericChoiceConditionView<Storage>::has_xyc() const {
+  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Equal</**/::emboss::test::ChoiceCondition::Field, bool, ::emboss::test::ChoiceCondition::Field, ::emboss::test::ChoiceCondition::Field>((field().Ok()    ? ::emboss::support::Maybe</**/::emboss::test::ChoiceCondition::Field>(static_cast</**/::emboss::test::ChoiceCondition::Field>(field().UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::ChoiceCondition::Field>()), ::emboss::support::Maybe</**/::emboss::test::ChoiceCondition::Field>(static_cast</**/::emboss::test::ChoiceCondition::Field>(1))), (x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), (y().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(y().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>())), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
+}
+
+
+template <class Storage>
+inline typename GenericChoiceConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericChoiceConditionView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericChoiceConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericChoiceConditionView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace ChoiceCondition {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace ChoiceCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericChoiceConditionView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return ChoiceCondition::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericChoiceConditionView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return ChoiceCondition::MaxSizeInBytes();
+}
+
+namespace ChoiceCondition {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace ChoiceCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericChoiceConditionView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return ChoiceCondition::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericChoiceConditionView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return ChoiceCondition::MinSizeInBytes();
+}
+namespace ContainsBits {
+namespace EmbossReservedAnonymousField3 {
+
+}  // namespace EmbossReservedAnonymousField3
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 7>>
+
+ GenericEmbossReservedAnonymousField3View<Storage>::has_top()
+    const {
+
+  if ( has_has_top().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(7LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 7>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   7>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 7>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField3View<Storage>::has_has_top() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericEmbossReservedAnonymousField3View<Storage>::has_bottom()
+    const {
+
+  if ( has_has_bottom().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField3View<Storage>::has_has_bottom() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace EmbossReservedAnonymousField3 {
+inline constexpr ::std::int32_t IntrinsicSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField3
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField3View<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField3::IntrinsicSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField3View<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField3::IntrinsicSizeInBits();
+}
+
+namespace EmbossReservedAnonymousField3 {
+inline constexpr ::std::int32_t MaxSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField3
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField3View<Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField3::MaxSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField3View<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField3::MaxSizeInBits();
+}
+
+namespace EmbossReservedAnonymousField3 {
+inline constexpr ::std::int32_t MinSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField3
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField3View<Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField3::MinSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField3View<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField3::MinSizeInBits();
+}
+
+}  // namespace ContainsBits
+
+
+template <class Storage>
+inline typename ::emboss::test::ContainsBits::GenericEmbossReservedAnonymousField3View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericContainsBitsView<Storage>::emboss_reserved_anonymous_field_3()
+    const {
+
+  if ( has_emboss_reserved_anonymous_field_3().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::ContainsBits::GenericEmbossReservedAnonymousField3View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::ContainsBits::GenericEmbossReservedAnonymousField3View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericContainsBitsView<Storage>::has_emboss_reserved_anonymous_field_3() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericContainsBitsView<Storage>::has_has_top() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericContainsBitsView<Storage>::has_has_bottom() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+namespace ContainsBits {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace ContainsBits
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericContainsBitsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return ContainsBits::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericContainsBitsView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return ContainsBits::IntrinsicSizeInBytes();
+}
+
+namespace ContainsBits {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace ContainsBits
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericContainsBitsView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return ContainsBits::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericContainsBitsView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return ContainsBits::MaxSizeInBytes();
+}
+
+namespace ContainsBits {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace ContainsBits
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericContainsBitsView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return ContainsBits::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericContainsBitsView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return ContainsBits::MinSizeInBytes();
+}
+namespace ContainsContainsBits {
+
+}  // namespace ContainsContainsBits
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericContainsBitsView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericContainsContainsBitsView<Storage>::condition()
+    const {
+
+  if ( has_condition().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericContainsBitsView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericContainsBitsView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericContainsContainsBitsView<Storage>::has_condition() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericContainsContainsBitsView<Storage>::top()
+    const {
+
+  if ( has_top().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericContainsContainsBitsView<Storage>::has_top() const {
+  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((condition().has_top().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(condition().has_top().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+}
+
+
+template <class Storage>
+inline typename GenericContainsContainsBitsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericContainsContainsBitsView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericContainsContainsBitsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericContainsContainsBitsView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace ContainsContainsBits {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace ContainsContainsBits
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericContainsContainsBitsView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return ContainsContainsBits::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericContainsContainsBitsView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return ContainsContainsBits::MaxSizeInBytes();
+}
+
+namespace ContainsContainsBits {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace ContainsContainsBits
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericContainsContainsBitsView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return ContainsContainsBits::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericContainsContainsBitsView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return ContainsContainsBits::MinSizeInBytes();
+}
+namespace ConditionalInline {
+namespace Type0 {
+
+}  // namespace Type0
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericType0View<Storage>::a()
+    const {
+
+  if ( has_a().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericType0View<Storage>::has_a() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericType0View<Storage>::b()
+    const {
+
+  if ( has_b().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericType0View<Storage>::has_b() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ GenericType0View<Storage>::c()
+    const {
+
+  if ( has_c().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericType0View<Storage>::has_c() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Type0 {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace Type0
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericType0View<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Type0::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericType0View<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Type0::IntrinsicSizeInBytes();
+}
+
+namespace Type0 {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace Type0
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericType0View<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Type0::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericType0View<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Type0::MaxSizeInBytes();
+}
+
+namespace Type0 {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace Type0
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericType0View<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Type0::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericType0View<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Type0::MinSizeInBytes();
+}
+
+namespace Type1 {
+
+}  // namespace Type1
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericType1View<Storage>::a()
+    const {
+
+  if ( has_a().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericType1View<Storage>::has_a() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericType1View<Storage>::b()
+    const {
+
+  if ( has_b().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericType1View<Storage>::has_b() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ GenericType1View<Storage>::c()
+    const {
+
+  if ( has_c().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericType1View<Storage>::has_c() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Type1 {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace Type1
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericType1View<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Type1::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericType1View<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Type1::IntrinsicSizeInBytes();
+}
+
+namespace Type1 {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace Type1
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericType1View<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Type1::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericType1View<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Type1::MaxSizeInBytes();
+}
+
+namespace Type1 {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace Type1
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericType1View<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Type1::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericType1View<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Type1::MinSizeInBytes();
+}
+
+}  // namespace ConditionalInline
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericConditionalInlineView<Storage>::payload_id()
+    const {
+
+  if ( has_payload_id().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionalInlineView<Storage>::has_payload_id() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::ConditionalInline::GenericType0View<typename Storage::template OffsetStorageType</**/0, 1>>
+
+ GenericConditionalInlineView<Storage>::type_0()
+    const {
+
+  if ( has_type_0().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::ConditionalInline::GenericType0View<typename Storage::template OffsetStorageType</**/0, 1>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::ConditionalInline::GenericType0View<typename Storage::template OffsetStorageType</**/0, 1>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionalInlineView<Storage>::has_type_0() const {
+  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((payload_id().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(payload_id().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::ConditionalInline::GenericType1View<typename Storage::template OffsetStorageType</**/0, 1>>
+
+ GenericConditionalInlineView<Storage>::type_1()
+    const {
+
+  if ( has_type_1().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::ConditionalInline::GenericType1View<typename Storage::template OffsetStorageType</**/0, 1>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::ConditionalInline::GenericType1View<typename Storage::template OffsetStorageType</**/0, 1>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionalInlineView<Storage>::has_type_1() const {
+  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((payload_id().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(payload_id().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+}
+
+
+template <class Storage>
+inline typename GenericConditionalInlineView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericConditionalInlineView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericConditionalInlineView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionalInlineView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace ConditionalInline {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace ConditionalInline
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalInlineView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return ConditionalInline::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalInlineView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return ConditionalInline::MaxSizeInBytes();
+}
+
+namespace ConditionalInline {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace ConditionalInline
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalInlineView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return ConditionalInline::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalInlineView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return ConditionalInline::MinSizeInBytes();
+}
+namespace ConditionalAnonymous {
+namespace EmbossReservedAnonymousField2 {
+
+}  // namespace EmbossReservedAnonymousField2
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericEmbossReservedAnonymousField2View<Storage>::low()
+    const {
+
+  if ( has_low().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField2View<Storage>::has_low() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<2, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 3>>
+
+ GenericEmbossReservedAnonymousField2View<Storage>::mid()
+    const {
+
+  if ( has_mid().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<2, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 3>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   3>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<2, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 3>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField2View<Storage>::has_mid() const {
+  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((low().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(low().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 7>>
+
+ GenericEmbossReservedAnonymousField2View<Storage>::high()
+    const {
+
+  if ( has_high().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(7LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 7>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   7>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 7>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField2View<Storage>::has_high() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace EmbossReservedAnonymousField2 {
+inline constexpr ::std::int32_t IntrinsicSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField2
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField2View<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField2::IntrinsicSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField2View<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField2::IntrinsicSizeInBits();
+}
+
+namespace EmbossReservedAnonymousField2 {
+inline constexpr ::std::int32_t MaxSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField2
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField2View<Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField2::MaxSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField2View<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField2::MaxSizeInBits();
+}
+
+namespace EmbossReservedAnonymousField2 {
+inline constexpr ::std::int32_t MinSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField2
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField2View<Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField2::MinSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField2View<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField2::MinSizeInBits();
+}
+
+}  // namespace ConditionalAnonymous
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericConditionalAnonymousView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionalAnonymousView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::ConditionalAnonymous::GenericEmbossReservedAnonymousField2View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericConditionalAnonymousView<Storage>::emboss_reserved_anonymous_field_2()
+    const {
+
+  if ( has_emboss_reserved_anonymous_field_2().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::ConditionalAnonymous::GenericEmbossReservedAnonymousField2View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::ConditionalAnonymous::GenericEmbossReservedAnonymousField2View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionalAnonymousView<Storage>::has_emboss_reserved_anonymous_field_2() const {
+  return ::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)));
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionalAnonymousView<Storage>::has_low() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(has_emboss_reserved_anonymous_field_2(), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionalAnonymousView<Storage>::has_mid() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(has_emboss_reserved_anonymous_field_2(), emboss_reserved_anonymous_field_2().has_mid());
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionalAnonymousView<Storage>::has_high() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(has_emboss_reserved_anonymous_field_2(), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+template <class Storage>
+inline typename GenericConditionalAnonymousView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericConditionalAnonymousView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericConditionalAnonymousView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionalAnonymousView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace ConditionalAnonymous {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace ConditionalAnonymous
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalAnonymousView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return ConditionalAnonymous::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalAnonymousView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return ConditionalAnonymous::MaxSizeInBytes();
+}
+
+namespace ConditionalAnonymous {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace ConditionalAnonymous
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalAnonymousView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return ConditionalAnonymous::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalAnonymousView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return ConditionalAnonymous::MinSizeInBytes();
+}
+namespace ConditionalOnFlag {
+namespace EmbossReservedAnonymousField1 {
+
+}  // namespace EmbossReservedAnonymousField1
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericEmbossReservedAnonymousField1View<Storage>::enabled()
+    const {
+
+  if ( has_enabled().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField1View<Storage>::has_enabled() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace EmbossReservedAnonymousField1 {
+inline constexpr ::std::int32_t IntrinsicSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField1
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField1::IntrinsicSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField1::IntrinsicSizeInBits();
+}
+
+namespace EmbossReservedAnonymousField1 {
+inline constexpr ::std::int32_t MaxSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField1
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField1::MaxSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField1::MaxSizeInBits();
+}
+
+namespace EmbossReservedAnonymousField1 {
+inline constexpr ::std::int32_t MinSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField1
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField1::MinSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField1::MinSizeInBits();
+}
+
+}  // namespace ConditionalOnFlag
+
+
+template <class Storage>
+inline typename ::emboss::test::ConditionalOnFlag::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericConditionalOnFlagView<Storage>::emboss_reserved_anonymous_field_1()
+    const {
+
+  if ( has_emboss_reserved_anonymous_field_1().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::ConditionalOnFlag::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::ConditionalOnFlag::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionalOnFlagView<Storage>::has_emboss_reserved_anonymous_field_1() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionalOnFlagView<Storage>::has_enabled() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericConditionalOnFlagView<Storage>::value()
+    const {
+
+  if ( has_value().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionalOnFlagView<Storage>::has_value() const {
+  return (enabled().Ok()    ? ::emboss::support::Maybe</**/bool>(static_cast</**/bool>(enabled().UncheckedRead()))    : ::emboss::support::Maybe</**/bool>());
+}
+
+
+template <class Storage>
+inline typename GenericConditionalOnFlagView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericConditionalOnFlagView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericConditionalOnFlagView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConditionalOnFlagView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace ConditionalOnFlag {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace ConditionalOnFlag
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalOnFlagView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return ConditionalOnFlag::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalOnFlagView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return ConditionalOnFlag::MaxSizeInBytes();
+}
+
+namespace ConditionalOnFlag {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace ConditionalOnFlag
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalOnFlagView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return ConditionalOnFlag::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConditionalOnFlagView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return ConditionalOnFlag::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_CONDITION_EMB_H_
+
diff --git a/testdata/golden_cpp/cpp_namespace.emb.h b/testdata/golden_cpp/cpp_namespace.emb.h
new file mode 100644
index 0000000..9fa38e4
--- /dev/null
+++ b/testdata/golden_cpp/cpp_namespace.emb.h
@@ -0,0 +1,126 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_CPP_NAMESPACE_EMB_H_
+#define TESTDATA_CPP_NAMESPACE_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace no_leading_double_colon {
+enum class Foo : ::std::uint64_t;
+
+
+enum class Foo : ::std::uint64_t {
+  VALUE = static_cast</**/::std::int32_t>(11LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<Foo> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   Foo *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("VALUE", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Foo::VALUE;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      Foo emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Foo::VALUE: return "VALUE";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(Foo emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Foo::VALUE: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       Foo emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<Foo>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    Foo *emboss_reserved_local_result) {
+  return EnumTraits<Foo>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    Foo emboss_reserved_local_value) {
+  return EnumTraits<Foo>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(Foo emboss_reserved_local_value) {
+  return EnumTraits<Foo>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    Foo emboss_reserved_local_value) {
+  return EnumTraits<Foo>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+
+
+
+
+}  // namespace no_leading_double_colon
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_CPP_NAMESPACE_EMB_H_
+
diff --git a/testdata/golden_cpp/dynamic_size.emb.h b/testdata/golden_cpp/dynamic_size.emb.h
new file mode 100644
index 0000000..8c5f5b5
--- /dev/null
+++ b/testdata/golden_cpp/dynamic_size.emb.h
@@ -0,0 +1,10433 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_DYNAMIC_SIZE_EMB_H_
+#define TESTDATA_DYNAMIC_SIZE_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace Message {
+
+}  // namespace Message
+
+
+template <class Storage>
+class GenericMessageView;
+
+namespace Image {
+
+}  // namespace Image
+
+
+template <class Storage>
+class GenericImageView;
+
+namespace TwoRegions {
+
+}  // namespace TwoRegions
+
+
+template <class Storage>
+class GenericTwoRegionsView;
+
+namespace MultipliedSize {
+
+}  // namespace MultipliedSize
+
+
+template <class Storage>
+class GenericMultipliedSizeView;
+
+namespace NegativeTermsInSizes {
+
+}  // namespace NegativeTermsInSizes
+
+
+template <class Storage>
+class GenericNegativeTermsInSizesView;
+
+namespace NegativeTermInLocation {
+
+}  // namespace NegativeTermInLocation
+
+
+template <class Storage>
+class GenericNegativeTermInLocationView;
+
+namespace ChainedSize {
+
+}  // namespace ChainedSize
+
+
+template <class Storage>
+class GenericChainedSizeView;
+
+namespace FinalFieldOverlaps {
+
+}  // namespace FinalFieldOverlaps
+
+
+template <class Storage>
+class GenericFinalFieldOverlapsView;
+
+namespace DynamicFinalFieldOverlaps {
+
+}  // namespace DynamicFinalFieldOverlaps
+
+
+template <class Storage>
+class GenericDynamicFinalFieldOverlapsView;
+
+namespace DynamicFieldDependsOnLaterField {
+
+}  // namespace DynamicFieldDependsOnLaterField
+
+
+template <class Storage>
+class GenericDynamicFieldDependsOnLaterFieldView;
+
+namespace DynamicFieldDoesNotAffectSize {
+
+}  // namespace DynamicFieldDoesNotAffectSize
+
+
+template <class Storage>
+class GenericDynamicFieldDoesNotAffectSizeView;
+
+
+
+
+
+
+
+
+
+namespace Message {
+
+}  // namespace Message
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericMessageView;
+
+template <class Storage>
+class GenericMessageView final {
+ public:
+  GenericMessageView() : backing_() {}
+  explicit GenericMessageView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericMessageView(
+      const GenericMessageView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericMessageView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericMessageView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericMessageView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericMessageView<Storage> &operator=(
+      const GenericMessageView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_header_length().Known()) return false;
+    if (has_header_length().ValueOrDefault() && !header_length().Ok()) return false;
+
+
+    if (!has_message_length().Known()) return false;
+    if (has_message_length().ValueOrDefault() && !message_length().Ok()) return false;
+
+
+    if (!has_padding().Known()) return false;
+    if (has_padding().ValueOrDefault() && !padding().Ok()) return false;
+
+
+    if (!has_message().Known()) return false;
+    if (has_message().ValueOrDefault() && !message().Ok()) return false;
+
+
+    if (!has_crc32().Known()) return false;
+    if (has_crc32().ValueOrDefault() && !crc32().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericMessageView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_header_length().Known()) return false;
+    if (!emboss_reserved_local_other.has_header_length().Known()) return false;
+
+    if (emboss_reserved_local_other.has_header_length().ValueOrDefault() &&
+        !has_header_length().ValueOrDefault())
+      return false;
+    if (has_header_length().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_header_length().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_header_length().ValueOrDefault() &&
+        has_header_length().ValueOrDefault() &&
+        !header_length().Equals(emboss_reserved_local_other.header_length()))
+      return false;
+
+
+
+    if (!has_message_length().Known()) return false;
+    if (!emboss_reserved_local_other.has_message_length().Known()) return false;
+
+    if (emboss_reserved_local_other.has_message_length().ValueOrDefault() &&
+        !has_message_length().ValueOrDefault())
+      return false;
+    if (has_message_length().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_message_length().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_message_length().ValueOrDefault() &&
+        has_message_length().ValueOrDefault() &&
+        !message_length().Equals(emboss_reserved_local_other.message_length()))
+      return false;
+
+
+
+    if (!has_padding().Known()) return false;
+    if (!emboss_reserved_local_other.has_padding().Known()) return false;
+
+    if (emboss_reserved_local_other.has_padding().ValueOrDefault() &&
+        !has_padding().ValueOrDefault())
+      return false;
+    if (has_padding().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_padding().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_padding().ValueOrDefault() &&
+        has_padding().ValueOrDefault() &&
+        !padding().Equals(emboss_reserved_local_other.padding()))
+      return false;
+
+
+
+    if (!has_message().Known()) return false;
+    if (!emboss_reserved_local_other.has_message().Known()) return false;
+
+    if (emboss_reserved_local_other.has_message().ValueOrDefault() &&
+        !has_message().ValueOrDefault())
+      return false;
+    if (has_message().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_message().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_message().ValueOrDefault() &&
+        has_message().ValueOrDefault() &&
+        !message().Equals(emboss_reserved_local_other.message()))
+      return false;
+
+
+
+    if (!has_crc32().Known()) return false;
+    if (!emboss_reserved_local_other.has_crc32().Known()) return false;
+
+    if (emboss_reserved_local_other.has_crc32().ValueOrDefault() &&
+        !has_crc32().ValueOrDefault())
+      return false;
+    if (has_crc32().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_crc32().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_crc32().ValueOrDefault() &&
+        has_crc32().ValueOrDefault() &&
+        !crc32().Equals(emboss_reserved_local_other.crc32()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericMessageView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_header_length().ValueOr(false) &&
+        !has_header_length().ValueOr(false))
+      return false;
+    if (has_header_length().ValueOr(false) &&
+        !emboss_reserved_local_other.has_header_length().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_header_length().ValueOr(false) &&
+        has_header_length().ValueOr(false) &&
+        !header_length().UncheckedEquals(emboss_reserved_local_other.header_length()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_message_length().ValueOr(false) &&
+        !has_message_length().ValueOr(false))
+      return false;
+    if (has_message_length().ValueOr(false) &&
+        !emboss_reserved_local_other.has_message_length().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_message_length().ValueOr(false) &&
+        has_message_length().ValueOr(false) &&
+        !message_length().UncheckedEquals(emboss_reserved_local_other.message_length()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_padding().ValueOr(false) &&
+        !has_padding().ValueOr(false))
+      return false;
+    if (has_padding().ValueOr(false) &&
+        !emboss_reserved_local_other.has_padding().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_padding().ValueOr(false) &&
+        has_padding().ValueOr(false) &&
+        !padding().UncheckedEquals(emboss_reserved_local_other.padding()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_message().ValueOr(false) &&
+        !has_message().ValueOr(false))
+      return false;
+    if (has_message().ValueOr(false) &&
+        !emboss_reserved_local_other.has_message().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_message().ValueOr(false) &&
+        has_message().ValueOr(false) &&
+        !message().UncheckedEquals(emboss_reserved_local_other.message()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_crc32().ValueOr(false) &&
+        !has_crc32().ValueOr(false))
+      return false;
+    if (has_crc32().ValueOr(false) &&
+        !emboss_reserved_local_other.has_crc32().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_crc32().ValueOr(false) &&
+        has_crc32().ValueOr(false) &&
+        !crc32().UncheckedEquals(emboss_reserved_local_other.crc32()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericMessageView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericMessageView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericMessageView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "header_length") {
+        if (!header_length().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "message_length") {
+        if (!message_length().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "padding") {
+        if (!padding().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "message") {
+        if (!message().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "crc32") {
+        if (!crc32().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_header_length().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          header_length().IsAggregate() || header_length().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("header_length: ");
+        header_length().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !header_length().IsAggregate() && !header_length().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# header_length: UNREADABLE\n");
+      }
+    }
+
+    if (has_message_length().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          message_length().IsAggregate() || message_length().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("message_length: ");
+        message_length().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !message_length().IsAggregate() && !message_length().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# message_length: UNREADABLE\n");
+      }
+    }
+
+    if (has_padding().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          padding().IsAggregate() || padding().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("padding: ");
+        padding().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !padding().IsAggregate() && !padding().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# padding: UNREADABLE\n");
+      }
+    }
+
+    if (has_message().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          message().IsAggregate() || message().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("message: ");
+        message().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !message().IsAggregate() && !message().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# message: UNREADABLE\n");
+      }
+    }
+
+    if (has_crc32().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          crc32().IsAggregate() || crc32().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("crc32: ");
+        crc32().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !crc32().IsAggregate() && !crc32().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# crc32: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ header_length() const;
+  ::emboss::support::Maybe<bool> has_header_length() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ message_length() const;
+  ::emboss::support::Maybe<bool> has_message_length() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 2>, 1,
+    8 >
+
+ padding() const;
+  ::emboss::support::Maybe<bool> has_padding() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/1, 0>, 1,
+    8 >
+
+ message() const;
+  ::emboss::support::Maybe<bool> has_message() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 32>>
+
+ crc32() const;
+  ::emboss::support::Maybe<bool> has_crc32() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericMessageView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.header_length();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), emboss_reserved_local_subexpr_3);
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_4, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_6 = view_.message_length();
+      const auto emboss_reserved_local_subexpr_7 = (emboss_reserved_local_subexpr_6.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_6.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_8 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_7);
+      const auto emboss_reserved_local_subexpr_9 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_8, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_10 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_8, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)));
+      const auto emboss_reserved_local_subexpr_11 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_10, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_12 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), emboss_reserved_local_subexpr_5, emboss_reserved_local_subexpr_9, emboss_reserved_local_subexpr_11);
+
+      return emboss_reserved_local_subexpr_12;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericMessageView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericMessageView;
+};
+using MessageView =
+    GenericMessageView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using MessageWriter =
+    GenericMessageView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericMessageView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericMessageView<
+    GenericMessageView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericMessageView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeMessageView( T &&emboss_reserved_local_arg) {
+  return GenericMessageView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericMessageView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeMessageView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericMessageView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericMessageView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedMessageView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericMessageView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace Image {
+
+}  // namespace Image
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericImageView;
+
+template <class Storage>
+class GenericImageView final {
+ public:
+  GenericImageView() : backing_() {}
+  explicit GenericImageView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericImageView(
+      const GenericImageView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericImageView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericImageView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericImageView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericImageView<Storage> &operator=(
+      const GenericImageView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_size().Known()) return false;
+    if (has_size().ValueOrDefault() && !size().Ok()) return false;
+
+
+    if (!has_pixels().Known()) return false;
+    if (has_pixels().ValueOrDefault() && !pixels().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericImageView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_size().Known()) return false;
+    if (!emboss_reserved_local_other.has_size().Known()) return false;
+
+    if (emboss_reserved_local_other.has_size().ValueOrDefault() &&
+        !has_size().ValueOrDefault())
+      return false;
+    if (has_size().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_size().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_size().ValueOrDefault() &&
+        has_size().ValueOrDefault() &&
+        !size().Equals(emboss_reserved_local_other.size()))
+      return false;
+
+
+
+    if (!has_pixels().Known()) return false;
+    if (!emboss_reserved_local_other.has_pixels().Known()) return false;
+
+    if (emboss_reserved_local_other.has_pixels().ValueOrDefault() &&
+        !has_pixels().ValueOrDefault())
+      return false;
+    if (has_pixels().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_pixels().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_pixels().ValueOrDefault() &&
+        has_pixels().ValueOrDefault() &&
+        !pixels().Equals(emboss_reserved_local_other.pixels()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericImageView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_size().ValueOr(false) &&
+        !has_size().ValueOr(false))
+      return false;
+    if (has_size().ValueOr(false) &&
+        !emboss_reserved_local_other.has_size().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_size().ValueOr(false) &&
+        has_size().ValueOr(false) &&
+        !size().UncheckedEquals(emboss_reserved_local_other.size()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_pixels().ValueOr(false) &&
+        !has_pixels().ValueOr(false))
+      return false;
+    if (has_pixels().ValueOr(false) &&
+        !emboss_reserved_local_other.has_pixels().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_pixels().ValueOr(false) &&
+        has_pixels().ValueOr(false) &&
+        !pixels().UncheckedEquals(emboss_reserved_local_other.pixels()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericImageView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericImageView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericImageView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "size") {
+        if (!size().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "pixels") {
+        if (!pixels().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_size().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          size().IsAggregate() || size().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("size: ");
+        size().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !size().IsAggregate() && !size().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# size: UNREADABLE\n");
+      }
+    }
+
+    if (has_pixels().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          pixels().IsAggregate() || pixels().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("pixels: ");
+        pixels().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !pixels().IsAggregate() && !pixels().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# pixels: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ size() const;
+  ::emboss::support::Maybe<bool> has_size() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::support::GenericArrayView<
+    typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/15, 0>::template OffsetStorageType</**/3, 0>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/15, 0>::template OffsetStorageType</**/3, 0>, 1,
+    8 >
+
+, typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/15, 0>, 3,
+    8 >
+
+, typename Storage::template OffsetStorageType</**/0, 1>, 15,
+    8 >
+
+ pixels() const;
+  ::emboss::support::Maybe<bool> has_pixels() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericImageView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.size();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Product</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(15LL)), emboss_reserved_local_subexpr_2);
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_3);
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_4, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_5);
+
+      return emboss_reserved_local_subexpr_6;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericImageView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericImageView;
+};
+using ImageView =
+    GenericImageView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ImageWriter =
+    GenericImageView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericImageView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericImageView<
+    GenericImageView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericImageView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeImageView( T &&emboss_reserved_local_arg) {
+  return GenericImageView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericImageView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeImageView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericImageView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericImageView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedImageView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericImageView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+
+
+
+namespace TwoRegions {
+
+}  // namespace TwoRegions
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericTwoRegionsView;
+
+template <class Storage>
+class GenericTwoRegionsView final {
+ public:
+  GenericTwoRegionsView() : backing_() {}
+  explicit GenericTwoRegionsView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericTwoRegionsView(
+      const GenericTwoRegionsView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericTwoRegionsView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericTwoRegionsView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericTwoRegionsView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericTwoRegionsView<Storage> &operator=(
+      const GenericTwoRegionsView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_b_end().Known()) return false;
+    if (has_b_end().ValueOrDefault() && !b_end().Ok()) return false;
+
+
+    if (!has_b_start().Known()) return false;
+    if (has_b_start().ValueOrDefault() && !b_start().Ok()) return false;
+
+
+    if (!has_a_size().Known()) return false;
+    if (has_a_size().ValueOrDefault() && !a_size().Ok()) return false;
+
+
+    if (!has_a_start().Known()) return false;
+    if (has_a_start().ValueOrDefault() && !a_start().Ok()) return false;
+
+
+    if (!has_region_a().Known()) return false;
+    if (has_region_a().ValueOrDefault() && !region_a().Ok()) return false;
+
+
+    if (!has_region_b().Known()) return false;
+    if (has_region_b().ValueOrDefault() && !region_b().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericTwoRegionsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_b_end().Known()) return false;
+    if (!emboss_reserved_local_other.has_b_end().Known()) return false;
+
+    if (emboss_reserved_local_other.has_b_end().ValueOrDefault() &&
+        !has_b_end().ValueOrDefault())
+      return false;
+    if (has_b_end().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_b_end().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_b_end().ValueOrDefault() &&
+        has_b_end().ValueOrDefault() &&
+        !b_end().Equals(emboss_reserved_local_other.b_end()))
+      return false;
+
+
+
+    if (!has_b_start().Known()) return false;
+    if (!emboss_reserved_local_other.has_b_start().Known()) return false;
+
+    if (emboss_reserved_local_other.has_b_start().ValueOrDefault() &&
+        !has_b_start().ValueOrDefault())
+      return false;
+    if (has_b_start().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_b_start().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_b_start().ValueOrDefault() &&
+        has_b_start().ValueOrDefault() &&
+        !b_start().Equals(emboss_reserved_local_other.b_start()))
+      return false;
+
+
+
+    if (!has_a_size().Known()) return false;
+    if (!emboss_reserved_local_other.has_a_size().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a_size().ValueOrDefault() &&
+        !has_a_size().ValueOrDefault())
+      return false;
+    if (has_a_size().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a_size().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a_size().ValueOrDefault() &&
+        has_a_size().ValueOrDefault() &&
+        !a_size().Equals(emboss_reserved_local_other.a_size()))
+      return false;
+
+
+
+    if (!has_a_start().Known()) return false;
+    if (!emboss_reserved_local_other.has_a_start().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a_start().ValueOrDefault() &&
+        !has_a_start().ValueOrDefault())
+      return false;
+    if (has_a_start().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a_start().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a_start().ValueOrDefault() &&
+        has_a_start().ValueOrDefault() &&
+        !a_start().Equals(emboss_reserved_local_other.a_start()))
+      return false;
+
+
+
+    if (!has_region_a().Known()) return false;
+    if (!emboss_reserved_local_other.has_region_a().Known()) return false;
+
+    if (emboss_reserved_local_other.has_region_a().ValueOrDefault() &&
+        !has_region_a().ValueOrDefault())
+      return false;
+    if (has_region_a().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_region_a().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_region_a().ValueOrDefault() &&
+        has_region_a().ValueOrDefault() &&
+        !region_a().Equals(emboss_reserved_local_other.region_a()))
+      return false;
+
+
+
+    if (!has_region_b().Known()) return false;
+    if (!emboss_reserved_local_other.has_region_b().Known()) return false;
+
+    if (emboss_reserved_local_other.has_region_b().ValueOrDefault() &&
+        !has_region_b().ValueOrDefault())
+      return false;
+    if (has_region_b().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_region_b().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_region_b().ValueOrDefault() &&
+        has_region_b().ValueOrDefault() &&
+        !region_b().Equals(emboss_reserved_local_other.region_b()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericTwoRegionsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_b_end().ValueOr(false) &&
+        !has_b_end().ValueOr(false))
+      return false;
+    if (has_b_end().ValueOr(false) &&
+        !emboss_reserved_local_other.has_b_end().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_b_end().ValueOr(false) &&
+        has_b_end().ValueOr(false) &&
+        !b_end().UncheckedEquals(emboss_reserved_local_other.b_end()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_b_start().ValueOr(false) &&
+        !has_b_start().ValueOr(false))
+      return false;
+    if (has_b_start().ValueOr(false) &&
+        !emboss_reserved_local_other.has_b_start().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_b_start().ValueOr(false) &&
+        has_b_start().ValueOr(false) &&
+        !b_start().UncheckedEquals(emboss_reserved_local_other.b_start()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_a_size().ValueOr(false) &&
+        !has_a_size().ValueOr(false))
+      return false;
+    if (has_a_size().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a_size().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a_size().ValueOr(false) &&
+        has_a_size().ValueOr(false) &&
+        !a_size().UncheckedEquals(emboss_reserved_local_other.a_size()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_a_start().ValueOr(false) &&
+        !has_a_start().ValueOr(false))
+      return false;
+    if (has_a_start().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a_start().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a_start().ValueOr(false) &&
+        has_a_start().ValueOr(false) &&
+        !a_start().UncheckedEquals(emboss_reserved_local_other.a_start()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_region_a().ValueOr(false) &&
+        !has_region_a().ValueOr(false))
+      return false;
+    if (has_region_a().ValueOr(false) &&
+        !emboss_reserved_local_other.has_region_a().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_region_a().ValueOr(false) &&
+        has_region_a().ValueOr(false) &&
+        !region_a().UncheckedEquals(emboss_reserved_local_other.region_a()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_region_b().ValueOr(false) &&
+        !has_region_b().ValueOr(false))
+      return false;
+    if (has_region_b().ValueOr(false) &&
+        !emboss_reserved_local_other.has_region_b().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_region_b().ValueOr(false) &&
+        has_region_b().ValueOr(false) &&
+        !region_b().UncheckedEquals(emboss_reserved_local_other.region_b()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericTwoRegionsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericTwoRegionsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericTwoRegionsView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "b_end") {
+        if (!b_end().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "b_start") {
+        if (!b_start().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "a_size") {
+        if (!a_size().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "a_start") {
+        if (!a_start().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "region_a") {
+        if (!region_a().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "region_b") {
+        if (!region_b().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_b_end().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b_end().IsAggregate() || b_end().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("b_end: ");
+        b_end().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !b_end().IsAggregate() && !b_end().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b_end: UNREADABLE\n");
+      }
+    }
+
+    if (has_b_start().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b_start().IsAggregate() || b_start().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("b_start: ");
+        b_start().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !b_start().IsAggregate() && !b_start().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b_start: UNREADABLE\n");
+      }
+    }
+
+    if (has_a_size().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a_size().IsAggregate() || a_size().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a_size: ");
+        a_size().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a_size().IsAggregate() && !a_size().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a_size: UNREADABLE\n");
+      }
+    }
+
+    if (has_a_start().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a_start().IsAggregate() || a_start().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a_start: ");
+        a_start().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a_start().IsAggregate() && !a_start().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a_start: UNREADABLE\n");
+      }
+    }
+
+    if (has_region_a().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          region_a().IsAggregate() || region_a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("region_a: ");
+        region_a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !region_a().IsAggregate() && !region_a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# region_a: UNREADABLE\n");
+      }
+    }
+
+    if (has_region_b().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          region_b().IsAggregate() || region_b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("region_b: ");
+        region_b().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !region_b().IsAggregate() && !region_b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# region_b: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 8>>
+
+ b_end() const;
+  ::emboss::support::Maybe<bool> has_b_end() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ b_start() const;
+  ::emboss::support::Maybe<bool> has_b_start() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ a_size() const;
+  ::emboss::support::Maybe<bool> has_a_size() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ a_start() const;
+  ::emboss::support::Maybe<bool> has_a_start() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/1, 0>, 1,
+    8 >
+
+ region_a() const;
+  ::emboss::support::Maybe<bool> has_region_a() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/1, 0>, 1,
+    8 >
+
+ region_b() const;
+  ::emboss::support::Maybe<bool> has_region_b() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericTwoRegionsView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.a_start();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = view_.a_size();
+      const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_4);
+      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_5, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_7 = view_.b_start();
+      const auto emboss_reserved_local_subexpr_8 = (emboss_reserved_local_subexpr_7.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_7.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_9 = view_.b_end();
+      const auto emboss_reserved_local_subexpr_10 = (emboss_reserved_local_subexpr_9.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_9.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_11 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_10, emboss_reserved_local_subexpr_8);
+      const auto emboss_reserved_local_subexpr_12 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_8, emboss_reserved_local_subexpr_11);
+      const auto emboss_reserved_local_subexpr_13 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_12, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_14 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_6, emboss_reserved_local_subexpr_13);
+
+      return emboss_reserved_local_subexpr_14;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericTwoRegionsView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericTwoRegionsView;
+};
+using TwoRegionsView =
+    GenericTwoRegionsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using TwoRegionsWriter =
+    GenericTwoRegionsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericTwoRegionsView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericTwoRegionsView<
+    GenericTwoRegionsView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericTwoRegionsView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeTwoRegionsView( T &&emboss_reserved_local_arg) {
+  return GenericTwoRegionsView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericTwoRegionsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeTwoRegionsView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericTwoRegionsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericTwoRegionsView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedTwoRegionsView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericTwoRegionsView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace MultipliedSize {
+
+}  // namespace MultipliedSize
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericMultipliedSizeView;
+
+template <class Storage>
+class GenericMultipliedSizeView final {
+ public:
+  GenericMultipliedSizeView() : backing_() {}
+  explicit GenericMultipliedSizeView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericMultipliedSizeView(
+      const GenericMultipliedSizeView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericMultipliedSizeView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericMultipliedSizeView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericMultipliedSizeView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericMultipliedSizeView<Storage> &operator=(
+      const GenericMultipliedSizeView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_width().Known()) return false;
+    if (has_width().ValueOrDefault() && !width().Ok()) return false;
+
+
+    if (!has_height().Known()) return false;
+    if (has_height().ValueOrDefault() && !height().Ok()) return false;
+
+
+    if (!has_data().Known()) return false;
+    if (has_data().ValueOrDefault() && !data().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericMultipliedSizeView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_width().Known()) return false;
+    if (!emboss_reserved_local_other.has_width().Known()) return false;
+
+    if (emboss_reserved_local_other.has_width().ValueOrDefault() &&
+        !has_width().ValueOrDefault())
+      return false;
+    if (has_width().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_width().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_width().ValueOrDefault() &&
+        has_width().ValueOrDefault() &&
+        !width().Equals(emboss_reserved_local_other.width()))
+      return false;
+
+
+
+    if (!has_height().Known()) return false;
+    if (!emboss_reserved_local_other.has_height().Known()) return false;
+
+    if (emboss_reserved_local_other.has_height().ValueOrDefault() &&
+        !has_height().ValueOrDefault())
+      return false;
+    if (has_height().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_height().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_height().ValueOrDefault() &&
+        has_height().ValueOrDefault() &&
+        !height().Equals(emboss_reserved_local_other.height()))
+      return false;
+
+
+
+    if (!has_data().Known()) return false;
+    if (!emboss_reserved_local_other.has_data().Known()) return false;
+
+    if (emboss_reserved_local_other.has_data().ValueOrDefault() &&
+        !has_data().ValueOrDefault())
+      return false;
+    if (has_data().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_data().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_data().ValueOrDefault() &&
+        has_data().ValueOrDefault() &&
+        !data().Equals(emboss_reserved_local_other.data()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericMultipliedSizeView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_width().ValueOr(false) &&
+        !has_width().ValueOr(false))
+      return false;
+    if (has_width().ValueOr(false) &&
+        !emboss_reserved_local_other.has_width().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_width().ValueOr(false) &&
+        has_width().ValueOr(false) &&
+        !width().UncheckedEquals(emboss_reserved_local_other.width()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_height().ValueOr(false) &&
+        !has_height().ValueOr(false))
+      return false;
+    if (has_height().ValueOr(false) &&
+        !emboss_reserved_local_other.has_height().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_height().ValueOr(false) &&
+        has_height().ValueOr(false) &&
+        !height().UncheckedEquals(emboss_reserved_local_other.height()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_data().ValueOr(false) &&
+        !has_data().ValueOr(false))
+      return false;
+    if (has_data().ValueOr(false) &&
+        !emboss_reserved_local_other.has_data().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_data().ValueOr(false) &&
+        has_data().ValueOr(false) &&
+        !data().UncheckedEquals(emboss_reserved_local_other.data()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericMultipliedSizeView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericMultipliedSizeView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericMultipliedSizeView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "width") {
+        if (!width().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "height") {
+        if (!height().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "data") {
+        if (!data().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_width().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          width().IsAggregate() || width().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("width: ");
+        width().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !width().IsAggregate() && !width().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# width: UNREADABLE\n");
+      }
+    }
+
+    if (has_height().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          height().IsAggregate() || height().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("height: ");
+        height().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !height().IsAggregate() && !height().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# height: UNREADABLE\n");
+      }
+    }
+
+    if (has_data().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          data().IsAggregate() || data().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("data: ");
+        data().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !data().IsAggregate() && !data().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# data: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ width() const;
+  ::emboss::support::Maybe<bool> has_width() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ height() const;
+  ::emboss::support::Maybe<bool> has_height() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 2>, 1,
+    8 >
+
+ data() const;
+  ::emboss::support::Maybe<bool> has_data() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericMultipliedSizeView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.width();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = view_.height();
+      const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Product</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_4);
+      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), emboss_reserved_local_subexpr_5);
+      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_6, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_8 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), emboss_reserved_local_subexpr_7);
+
+      return emboss_reserved_local_subexpr_8;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericMultipliedSizeView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericMultipliedSizeView;
+};
+using MultipliedSizeView =
+    GenericMultipliedSizeView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using MultipliedSizeWriter =
+    GenericMultipliedSizeView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericMultipliedSizeView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericMultipliedSizeView<
+    GenericMultipliedSizeView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericMultipliedSizeView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeMultipliedSizeView( T &&emboss_reserved_local_arg) {
+  return GenericMultipliedSizeView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericMultipliedSizeView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeMultipliedSizeView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericMultipliedSizeView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericMultipliedSizeView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedMultipliedSizeView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericMultipliedSizeView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+
+
+
+
+
+
+namespace NegativeTermsInSizes {
+
+}  // namespace NegativeTermsInSizes
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericNegativeTermsInSizesView;
+
+template <class Storage>
+class GenericNegativeTermsInSizesView final {
+ public:
+  GenericNegativeTermsInSizesView() : backing_() {}
+  explicit GenericNegativeTermsInSizesView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericNegativeTermsInSizesView(
+      const GenericNegativeTermsInSizesView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericNegativeTermsInSizesView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericNegativeTermsInSizesView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericNegativeTermsInSizesView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericNegativeTermsInSizesView<Storage> &operator=(
+      const GenericNegativeTermsInSizesView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_a().Known()) return false;
+    if (has_a().ValueOrDefault() && !a().Ok()) return false;
+
+
+    if (!has_b().Known()) return false;
+    if (has_b().ValueOrDefault() && !b().Ok()) return false;
+
+
+    if (!has_c().Known()) return false;
+    if (has_c().ValueOrDefault() && !c().Ok()) return false;
+
+
+    if (!has_a_minus_b().Known()) return false;
+    if (has_a_minus_b().ValueOrDefault() && !a_minus_b().Ok()) return false;
+
+
+    if (!has_a_minus_2b().Known()) return false;
+    if (has_a_minus_2b().ValueOrDefault() && !a_minus_2b().Ok()) return false;
+
+
+    if (!has_a_minus_b_minus_c().Known()) return false;
+    if (has_a_minus_b_minus_c().ValueOrDefault() && !a_minus_b_minus_c().Ok()) return false;
+
+
+    if (!has_ten_minus_a().Known()) return false;
+    if (has_ten_minus_a().ValueOrDefault() && !ten_minus_a().Ok()) return false;
+
+
+    if (!has_a_minus_2c().Known()) return false;
+    if (has_a_minus_2c().ValueOrDefault() && !a_minus_2c().Ok()) return false;
+
+
+    if (!has_a_minus_c().Known()) return false;
+    if (has_a_minus_c().ValueOrDefault() && !a_minus_c().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericNegativeTermsInSizesView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_a().Known()) return false;
+    if (!emboss_reserved_local_other.has_a().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        !has_a().ValueOrDefault())
+      return false;
+    if (has_a().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        has_a().ValueOrDefault() &&
+        !a().Equals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (!has_b().Known()) return false;
+    if (!emboss_reserved_local_other.has_b().Known()) return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        !has_b().ValueOrDefault())
+      return false;
+    if (has_b().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_b().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        has_b().ValueOrDefault() &&
+        !b().Equals(emboss_reserved_local_other.b()))
+      return false;
+
+
+
+    if (!has_c().Known()) return false;
+    if (!emboss_reserved_local_other.has_c().Known()) return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOrDefault() &&
+        !has_c().ValueOrDefault())
+      return false;
+    if (has_c().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_c().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOrDefault() &&
+        has_c().ValueOrDefault() &&
+        !c().Equals(emboss_reserved_local_other.c()))
+      return false;
+
+
+
+    if (!has_a_minus_b().Known()) return false;
+    if (!emboss_reserved_local_other.has_a_minus_b().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a_minus_b().ValueOrDefault() &&
+        !has_a_minus_b().ValueOrDefault())
+      return false;
+    if (has_a_minus_b().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a_minus_b().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a_minus_b().ValueOrDefault() &&
+        has_a_minus_b().ValueOrDefault() &&
+        !a_minus_b().Equals(emboss_reserved_local_other.a_minus_b()))
+      return false;
+
+
+
+    if (!has_a_minus_2b().Known()) return false;
+    if (!emboss_reserved_local_other.has_a_minus_2b().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a_minus_2b().ValueOrDefault() &&
+        !has_a_minus_2b().ValueOrDefault())
+      return false;
+    if (has_a_minus_2b().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a_minus_2b().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a_minus_2b().ValueOrDefault() &&
+        has_a_minus_2b().ValueOrDefault() &&
+        !a_minus_2b().Equals(emboss_reserved_local_other.a_minus_2b()))
+      return false;
+
+
+
+    if (!has_a_minus_b_minus_c().Known()) return false;
+    if (!emboss_reserved_local_other.has_a_minus_b_minus_c().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a_minus_b_minus_c().ValueOrDefault() &&
+        !has_a_minus_b_minus_c().ValueOrDefault())
+      return false;
+    if (has_a_minus_b_minus_c().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a_minus_b_minus_c().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a_minus_b_minus_c().ValueOrDefault() &&
+        has_a_minus_b_minus_c().ValueOrDefault() &&
+        !a_minus_b_minus_c().Equals(emboss_reserved_local_other.a_minus_b_minus_c()))
+      return false;
+
+
+
+    if (!has_ten_minus_a().Known()) return false;
+    if (!emboss_reserved_local_other.has_ten_minus_a().Known()) return false;
+
+    if (emboss_reserved_local_other.has_ten_minus_a().ValueOrDefault() &&
+        !has_ten_minus_a().ValueOrDefault())
+      return false;
+    if (has_ten_minus_a().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_ten_minus_a().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_ten_minus_a().ValueOrDefault() &&
+        has_ten_minus_a().ValueOrDefault() &&
+        !ten_minus_a().Equals(emboss_reserved_local_other.ten_minus_a()))
+      return false;
+
+
+
+    if (!has_a_minus_2c().Known()) return false;
+    if (!emboss_reserved_local_other.has_a_minus_2c().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a_minus_2c().ValueOrDefault() &&
+        !has_a_minus_2c().ValueOrDefault())
+      return false;
+    if (has_a_minus_2c().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a_minus_2c().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a_minus_2c().ValueOrDefault() &&
+        has_a_minus_2c().ValueOrDefault() &&
+        !a_minus_2c().Equals(emboss_reserved_local_other.a_minus_2c()))
+      return false;
+
+
+
+    if (!has_a_minus_c().Known()) return false;
+    if (!emboss_reserved_local_other.has_a_minus_c().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a_minus_c().ValueOrDefault() &&
+        !has_a_minus_c().ValueOrDefault())
+      return false;
+    if (has_a_minus_c().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a_minus_c().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a_minus_c().ValueOrDefault() &&
+        has_a_minus_c().ValueOrDefault() &&
+        !a_minus_c().Equals(emboss_reserved_local_other.a_minus_c()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericNegativeTermsInSizesView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        !has_a().ValueOr(false))
+      return false;
+    if (has_a().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        has_a().ValueOr(false) &&
+        !a().UncheckedEquals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        !has_b().ValueOr(false))
+      return false;
+    if (has_b().ValueOr(false) &&
+        !emboss_reserved_local_other.has_b().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        has_b().ValueOr(false) &&
+        !b().UncheckedEquals(emboss_reserved_local_other.b()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_c().ValueOr(false) &&
+        !has_c().ValueOr(false))
+      return false;
+    if (has_c().ValueOr(false) &&
+        !emboss_reserved_local_other.has_c().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOr(false) &&
+        has_c().ValueOr(false) &&
+        !c().UncheckedEquals(emboss_reserved_local_other.c()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_a_minus_b().ValueOr(false) &&
+        !has_a_minus_b().ValueOr(false))
+      return false;
+    if (has_a_minus_b().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a_minus_b().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a_minus_b().ValueOr(false) &&
+        has_a_minus_b().ValueOr(false) &&
+        !a_minus_b().UncheckedEquals(emboss_reserved_local_other.a_minus_b()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_a_minus_2b().ValueOr(false) &&
+        !has_a_minus_2b().ValueOr(false))
+      return false;
+    if (has_a_minus_2b().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a_minus_2b().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a_minus_2b().ValueOr(false) &&
+        has_a_minus_2b().ValueOr(false) &&
+        !a_minus_2b().UncheckedEquals(emboss_reserved_local_other.a_minus_2b()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_a_minus_b_minus_c().ValueOr(false) &&
+        !has_a_minus_b_minus_c().ValueOr(false))
+      return false;
+    if (has_a_minus_b_minus_c().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a_minus_b_minus_c().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a_minus_b_minus_c().ValueOr(false) &&
+        has_a_minus_b_minus_c().ValueOr(false) &&
+        !a_minus_b_minus_c().UncheckedEquals(emboss_reserved_local_other.a_minus_b_minus_c()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_ten_minus_a().ValueOr(false) &&
+        !has_ten_minus_a().ValueOr(false))
+      return false;
+    if (has_ten_minus_a().ValueOr(false) &&
+        !emboss_reserved_local_other.has_ten_minus_a().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_ten_minus_a().ValueOr(false) &&
+        has_ten_minus_a().ValueOr(false) &&
+        !ten_minus_a().UncheckedEquals(emboss_reserved_local_other.ten_minus_a()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_a_minus_2c().ValueOr(false) &&
+        !has_a_minus_2c().ValueOr(false))
+      return false;
+    if (has_a_minus_2c().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a_minus_2c().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a_minus_2c().ValueOr(false) &&
+        has_a_minus_2c().ValueOr(false) &&
+        !a_minus_2c().UncheckedEquals(emboss_reserved_local_other.a_minus_2c()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_a_minus_c().ValueOr(false) &&
+        !has_a_minus_c().ValueOr(false))
+      return false;
+    if (has_a_minus_c().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a_minus_c().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a_minus_c().ValueOr(false) &&
+        has_a_minus_c().ValueOr(false) &&
+        !a_minus_c().UncheckedEquals(emboss_reserved_local_other.a_minus_c()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericNegativeTermsInSizesView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericNegativeTermsInSizesView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericNegativeTermsInSizesView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "a") {
+        if (!a().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "b") {
+        if (!b().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "c") {
+        if (!c().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "a_minus_b") {
+        if (!a_minus_b().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "a_minus_2b") {
+        if (!a_minus_2b().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "a_minus_b_minus_c") {
+        if (!a_minus_b_minus_c().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "ten_minus_a") {
+        if (!ten_minus_a().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "a_minus_2c") {
+        if (!a_minus_2c().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "a_minus_c") {
+        if (!a_minus_c().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_a().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a().IsAggregate() || a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a: ");
+        a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a().IsAggregate() && !a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a: UNREADABLE\n");
+      }
+    }
+
+    if (has_b().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b().IsAggregate() || b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("b: ");
+        b().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !b().IsAggregate() && !b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b: UNREADABLE\n");
+      }
+    }
+
+    if (has_c().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          c().IsAggregate() || c().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("c: ");
+        c().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !c().IsAggregate() && !c().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# c: UNREADABLE\n");
+      }
+    }
+
+    if (has_a_minus_b().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a_minus_b().IsAggregate() || a_minus_b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a_minus_b: ");
+        a_minus_b().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a_minus_b().IsAggregate() && !a_minus_b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a_minus_b: UNREADABLE\n");
+      }
+    }
+
+    if (has_a_minus_2b().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a_minus_2b().IsAggregate() || a_minus_2b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a_minus_2b: ");
+        a_minus_2b().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a_minus_2b().IsAggregate() && !a_minus_2b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a_minus_2b: UNREADABLE\n");
+      }
+    }
+
+    if (has_a_minus_b_minus_c().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a_minus_b_minus_c().IsAggregate() || a_minus_b_minus_c().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a_minus_b_minus_c: ");
+        a_minus_b_minus_c().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a_minus_b_minus_c().IsAggregate() && !a_minus_b_minus_c().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a_minus_b_minus_c: UNREADABLE\n");
+      }
+    }
+
+    if (has_ten_minus_a().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          ten_minus_a().IsAggregate() || ten_minus_a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("ten_minus_a: ");
+        ten_minus_a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !ten_minus_a().IsAggregate() && !ten_minus_a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# ten_minus_a: UNREADABLE\n");
+      }
+    }
+
+    if (has_a_minus_2c().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a_minus_2c().IsAggregate() || a_minus_2c().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a_minus_2c: ");
+        a_minus_2c().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a_minus_2c().IsAggregate() && !a_minus_2c().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a_minus_2c: UNREADABLE\n");
+      }
+    }
+
+    if (has_a_minus_c().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a_minus_c().IsAggregate() || a_minus_c().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a_minus_c: ");
+        a_minus_c().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a_minus_c().IsAggregate() && !a_minus_c().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a_minus_c: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ a() const;
+  ::emboss::support::Maybe<bool> has_a() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ b() const;
+  ::emboss::support::Maybe<bool> has_b() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ c() const;
+  ::emboss::support::Maybe<bool> has_c() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+ a_minus_b() const;
+  ::emboss::support::Maybe<bool> has_a_minus_b() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+ a_minus_2b() const;
+  ::emboss::support::Maybe<bool> has_a_minus_2b() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+ a_minus_b_minus_c() const;
+  ::emboss::support::Maybe<bool> has_a_minus_b_minus_c() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+ ten_minus_a() const;
+  ::emboss::support::Maybe<bool> has_ten_minus_a() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+ a_minus_2c() const;
+  ::emboss::support::Maybe<bool> has_a_minus_2c() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+ a_minus_c() const;
+  ::emboss::support::Maybe<bool> has_a_minus_c() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericNegativeTermsInSizesView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.a();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = view_.b();
+      const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_4);
+      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_5, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)));
+      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)), emboss_reserved_local_subexpr_6);
+      const auto emboss_reserved_local_subexpr_8 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_7, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_9 = ::emboss::support::Product</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), emboss_reserved_local_subexpr_4);
+      const auto emboss_reserved_local_subexpr_10 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_9);
+      const auto emboss_reserved_local_subexpr_11 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_10, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)));
+      const auto emboss_reserved_local_subexpr_12 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)), emboss_reserved_local_subexpr_11);
+      const auto emboss_reserved_local_subexpr_13 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_12, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_14 = view_.c();
+      const auto emboss_reserved_local_subexpr_15 = (emboss_reserved_local_subexpr_14.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_14.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_16 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_5, emboss_reserved_local_subexpr_15);
+      const auto emboss_reserved_local_subexpr_17 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_16, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)));
+      const auto emboss_reserved_local_subexpr_18 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)), emboss_reserved_local_subexpr_17);
+      const auto emboss_reserved_local_subexpr_19 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_18, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_20 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(7LL)), emboss_reserved_local_subexpr_2);
+      const auto emboss_reserved_local_subexpr_21 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)), emboss_reserved_local_subexpr_20);
+      const auto emboss_reserved_local_subexpr_22 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_21, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_23 = ::emboss::support::Product</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), emboss_reserved_local_subexpr_15);
+      const auto emboss_reserved_local_subexpr_24 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_23);
+      const auto emboss_reserved_local_subexpr_25 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_24, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)));
+      const auto emboss_reserved_local_subexpr_26 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)), emboss_reserved_local_subexpr_25);
+      const auto emboss_reserved_local_subexpr_27 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_26, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_28 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_15);
+      const auto emboss_reserved_local_subexpr_29 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_28, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)));
+      const auto emboss_reserved_local_subexpr_30 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)), emboss_reserved_local_subexpr_29);
+      const auto emboss_reserved_local_subexpr_31 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_30, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_32 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)), emboss_reserved_local_subexpr_8, emboss_reserved_local_subexpr_13, emboss_reserved_local_subexpr_19, emboss_reserved_local_subexpr_22, emboss_reserved_local_subexpr_27, emboss_reserved_local_subexpr_31);
+
+      return emboss_reserved_local_subexpr_32;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericNegativeTermsInSizesView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericNegativeTermsInSizesView;
+};
+using NegativeTermsInSizesView =
+    GenericNegativeTermsInSizesView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using NegativeTermsInSizesWriter =
+    GenericNegativeTermsInSizesView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericNegativeTermsInSizesView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericNegativeTermsInSizesView<
+    GenericNegativeTermsInSizesView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericNegativeTermsInSizesView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeNegativeTermsInSizesView( T &&emboss_reserved_local_arg) {
+  return GenericNegativeTermsInSizesView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericNegativeTermsInSizesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeNegativeTermsInSizesView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericNegativeTermsInSizesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericNegativeTermsInSizesView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedNegativeTermsInSizesView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericNegativeTermsInSizesView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace NegativeTermInLocation {
+
+}  // namespace NegativeTermInLocation
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericNegativeTermInLocationView;
+
+template <class Storage>
+class GenericNegativeTermInLocationView final {
+ public:
+  GenericNegativeTermInLocationView() : backing_() {}
+  explicit GenericNegativeTermInLocationView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericNegativeTermInLocationView(
+      const GenericNegativeTermInLocationView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericNegativeTermInLocationView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericNegativeTermInLocationView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericNegativeTermInLocationView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericNegativeTermInLocationView<Storage> &operator=(
+      const GenericNegativeTermInLocationView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_a().Known()) return false;
+    if (has_a().ValueOrDefault() && !a().Ok()) return false;
+
+
+    if (!has_b().Known()) return false;
+    if (has_b().ValueOrDefault() && !b().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericNegativeTermInLocationView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_a().Known()) return false;
+    if (!emboss_reserved_local_other.has_a().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        !has_a().ValueOrDefault())
+      return false;
+    if (has_a().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        has_a().ValueOrDefault() &&
+        !a().Equals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (!has_b().Known()) return false;
+    if (!emboss_reserved_local_other.has_b().Known()) return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        !has_b().ValueOrDefault())
+      return false;
+    if (has_b().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_b().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        has_b().ValueOrDefault() &&
+        !b().Equals(emboss_reserved_local_other.b()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericNegativeTermInLocationView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        !has_a().ValueOr(false))
+      return false;
+    if (has_a().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        has_a().ValueOr(false) &&
+        !a().UncheckedEquals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        !has_b().ValueOr(false))
+      return false;
+    if (has_b().ValueOr(false) &&
+        !emboss_reserved_local_other.has_b().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        has_b().ValueOr(false) &&
+        !b().UncheckedEquals(emboss_reserved_local_other.b()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericNegativeTermInLocationView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericNegativeTermInLocationView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericNegativeTermInLocationView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "a") {
+        if (!a().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "b") {
+        if (!b().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_a().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a().IsAggregate() || a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a: ");
+        a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a().IsAggregate() && !a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a: UNREADABLE\n");
+      }
+    }
+
+    if (has_b().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b().IsAggregate() || b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("b: ");
+        b().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !b().IsAggregate() && !b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ a() const;
+  ::emboss::support::Maybe<bool> has_a() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+ b() const;
+  ::emboss::support::Maybe<bool> has_b() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericNegativeTermInLocationView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.a();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)), emboss_reserved_local_subexpr_2);
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_4, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_5);
+
+      return emboss_reserved_local_subexpr_6;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericNegativeTermInLocationView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericNegativeTermInLocationView;
+};
+using NegativeTermInLocationView =
+    GenericNegativeTermInLocationView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using NegativeTermInLocationWriter =
+    GenericNegativeTermInLocationView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericNegativeTermInLocationView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericNegativeTermInLocationView<
+    GenericNegativeTermInLocationView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericNegativeTermInLocationView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeNegativeTermInLocationView( T &&emboss_reserved_local_arg) {
+  return GenericNegativeTermInLocationView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericNegativeTermInLocationView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeNegativeTermInLocationView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericNegativeTermInLocationView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericNegativeTermInLocationView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedNegativeTermInLocationView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericNegativeTermInLocationView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+
+namespace ChainedSize {
+
+}  // namespace ChainedSize
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericChainedSizeView;
+
+template <class Storage>
+class GenericChainedSizeView final {
+ public:
+  GenericChainedSizeView() : backing_() {}
+  explicit GenericChainedSizeView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericChainedSizeView(
+      const GenericChainedSizeView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericChainedSizeView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericChainedSizeView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericChainedSizeView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericChainedSizeView<Storage> &operator=(
+      const GenericChainedSizeView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_a().Known()) return false;
+    if (has_a().ValueOrDefault() && !a().Ok()) return false;
+
+
+    if (!has_b().Known()) return false;
+    if (has_b().ValueOrDefault() && !b().Ok()) return false;
+
+
+    if (!has_c().Known()) return false;
+    if (has_c().ValueOrDefault() && !c().Ok()) return false;
+
+
+    if (!has_d().Known()) return false;
+    if (has_d().ValueOrDefault() && !d().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericChainedSizeView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_a().Known()) return false;
+    if (!emboss_reserved_local_other.has_a().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        !has_a().ValueOrDefault())
+      return false;
+    if (has_a().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        has_a().ValueOrDefault() &&
+        !a().Equals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (!has_b().Known()) return false;
+    if (!emboss_reserved_local_other.has_b().Known()) return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        !has_b().ValueOrDefault())
+      return false;
+    if (has_b().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_b().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        has_b().ValueOrDefault() &&
+        !b().Equals(emboss_reserved_local_other.b()))
+      return false;
+
+
+
+    if (!has_c().Known()) return false;
+    if (!emboss_reserved_local_other.has_c().Known()) return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOrDefault() &&
+        !has_c().ValueOrDefault())
+      return false;
+    if (has_c().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_c().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOrDefault() &&
+        has_c().ValueOrDefault() &&
+        !c().Equals(emboss_reserved_local_other.c()))
+      return false;
+
+
+
+    if (!has_d().Known()) return false;
+    if (!emboss_reserved_local_other.has_d().Known()) return false;
+
+    if (emboss_reserved_local_other.has_d().ValueOrDefault() &&
+        !has_d().ValueOrDefault())
+      return false;
+    if (has_d().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_d().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_d().ValueOrDefault() &&
+        has_d().ValueOrDefault() &&
+        !d().Equals(emboss_reserved_local_other.d()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericChainedSizeView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        !has_a().ValueOr(false))
+      return false;
+    if (has_a().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        has_a().ValueOr(false) &&
+        !a().UncheckedEquals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        !has_b().ValueOr(false))
+      return false;
+    if (has_b().ValueOr(false) &&
+        !emboss_reserved_local_other.has_b().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        has_b().ValueOr(false) &&
+        !b().UncheckedEquals(emboss_reserved_local_other.b()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_c().ValueOr(false) &&
+        !has_c().ValueOr(false))
+      return false;
+    if (has_c().ValueOr(false) &&
+        !emboss_reserved_local_other.has_c().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOr(false) &&
+        has_c().ValueOr(false) &&
+        !c().UncheckedEquals(emboss_reserved_local_other.c()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_d().ValueOr(false) &&
+        !has_d().ValueOr(false))
+      return false;
+    if (has_d().ValueOr(false) &&
+        !emboss_reserved_local_other.has_d().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_d().ValueOr(false) &&
+        has_d().ValueOr(false) &&
+        !d().UncheckedEquals(emboss_reserved_local_other.d()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericChainedSizeView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericChainedSizeView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericChainedSizeView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "a") {
+        if (!a().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "b") {
+        if (!b().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "c") {
+        if (!c().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "d") {
+        if (!d().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_a().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a().IsAggregate() || a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a: ");
+        a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a().IsAggregate() && !a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a: UNREADABLE\n");
+      }
+    }
+
+    if (has_b().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b().IsAggregate() || b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("b: ");
+        b().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !b().IsAggregate() && !b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b: UNREADABLE\n");
+      }
+    }
+
+    if (has_c().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          c().IsAggregate() || c().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("c: ");
+        c().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !c().IsAggregate() && !c().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# c: UNREADABLE\n");
+      }
+    }
+
+    if (has_d().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          d().IsAggregate() || d().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("d: ");
+        d().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !d().IsAggregate() && !d().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# d: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ a() const;
+  ::emboss::support::Maybe<bool> has_a() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+ b() const;
+  ::emboss::support::Maybe<bool> has_b() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+ c() const;
+  ::emboss::support::Maybe<bool> has_c() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+ d() const;
+  ::emboss::support::Maybe<bool> has_d() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericChainedSizeView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.a();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = view_.b();
+      const auto emboss_reserved_local_subexpr_6 = (emboss_reserved_local_subexpr_5.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_5.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_6, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      const auto emboss_reserved_local_subexpr_8 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_7, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_9 = view_.c();
+      const auto emboss_reserved_local_subexpr_10 = (emboss_reserved_local_subexpr_9.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_9.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_11 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_10, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      const auto emboss_reserved_local_subexpr_12 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_11, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_13 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_4, emboss_reserved_local_subexpr_8, emboss_reserved_local_subexpr_12);
+
+      return emboss_reserved_local_subexpr_13;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericChainedSizeView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericChainedSizeView;
+};
+using ChainedSizeView =
+    GenericChainedSizeView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ChainedSizeWriter =
+    GenericChainedSizeView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericChainedSizeView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericChainedSizeView<
+    GenericChainedSizeView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericChainedSizeView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeChainedSizeView( T &&emboss_reserved_local_arg) {
+  return GenericChainedSizeView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericChainedSizeView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeChainedSizeView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericChainedSizeView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericChainedSizeView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedChainedSizeView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericChainedSizeView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace FinalFieldOverlaps {
+
+}  // namespace FinalFieldOverlaps
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericFinalFieldOverlapsView;
+
+template <class Storage>
+class GenericFinalFieldOverlapsView final {
+ public:
+  GenericFinalFieldOverlapsView() : backing_() {}
+  explicit GenericFinalFieldOverlapsView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericFinalFieldOverlapsView(
+      const GenericFinalFieldOverlapsView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericFinalFieldOverlapsView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericFinalFieldOverlapsView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericFinalFieldOverlapsView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericFinalFieldOverlapsView<Storage> &operator=(
+      const GenericFinalFieldOverlapsView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_a().Known()) return false;
+    if (has_a().ValueOrDefault() && !a().Ok()) return false;
+
+
+    if (!has_b().Known()) return false;
+    if (has_b().ValueOrDefault() && !b().Ok()) return false;
+
+
+    if (!has_c().Known()) return false;
+    if (has_c().ValueOrDefault() && !c().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericFinalFieldOverlapsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_a().Known()) return false;
+    if (!emboss_reserved_local_other.has_a().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        !has_a().ValueOrDefault())
+      return false;
+    if (has_a().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        has_a().ValueOrDefault() &&
+        !a().Equals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (!has_b().Known()) return false;
+    if (!emboss_reserved_local_other.has_b().Known()) return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        !has_b().ValueOrDefault())
+      return false;
+    if (has_b().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_b().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        has_b().ValueOrDefault() &&
+        !b().Equals(emboss_reserved_local_other.b()))
+      return false;
+
+
+
+    if (!has_c().Known()) return false;
+    if (!emboss_reserved_local_other.has_c().Known()) return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOrDefault() &&
+        !has_c().ValueOrDefault())
+      return false;
+    if (has_c().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_c().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOrDefault() &&
+        has_c().ValueOrDefault() &&
+        !c().Equals(emboss_reserved_local_other.c()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericFinalFieldOverlapsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        !has_a().ValueOr(false))
+      return false;
+    if (has_a().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        has_a().ValueOr(false) &&
+        !a().UncheckedEquals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        !has_b().ValueOr(false))
+      return false;
+    if (has_b().ValueOr(false) &&
+        !emboss_reserved_local_other.has_b().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        has_b().ValueOr(false) &&
+        !b().UncheckedEquals(emboss_reserved_local_other.b()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_c().ValueOr(false) &&
+        !has_c().ValueOr(false))
+      return false;
+    if (has_c().ValueOr(false) &&
+        !emboss_reserved_local_other.has_c().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOr(false) &&
+        has_c().ValueOr(false) &&
+        !c().UncheckedEquals(emboss_reserved_local_other.c()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericFinalFieldOverlapsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericFinalFieldOverlapsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericFinalFieldOverlapsView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "a") {
+        if (!a().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "b") {
+        if (!b().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "c") {
+        if (!c().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_a().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a().IsAggregate() || a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a: ");
+        a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a().IsAggregate() && !a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a: UNREADABLE\n");
+      }
+    }
+
+    if (has_b().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b().IsAggregate() || b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("b: ");
+        b().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !b().IsAggregate() && !b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b: UNREADABLE\n");
+      }
+    }
+
+    if (has_c().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          c().IsAggregate() || c().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("c: ");
+        c().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !c().IsAggregate() && !c().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# c: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ a() const;
+  ::emboss::support::Maybe<bool> has_a() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 32>>
+
+ b() const;
+  ::emboss::support::Maybe<bool> has_b() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 16>>
+
+ c() const;
+  ::emboss::support::Maybe<bool> has_c() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericFinalFieldOverlapsView;
+};
+using FinalFieldOverlapsView =
+    GenericFinalFieldOverlapsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using FinalFieldOverlapsWriter =
+    GenericFinalFieldOverlapsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericFinalFieldOverlapsView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericFinalFieldOverlapsView<
+    GenericFinalFieldOverlapsView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericFinalFieldOverlapsView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeFinalFieldOverlapsView( T &&emboss_reserved_local_arg) {
+  return GenericFinalFieldOverlapsView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericFinalFieldOverlapsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeFinalFieldOverlapsView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericFinalFieldOverlapsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericFinalFieldOverlapsView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedFinalFieldOverlapsView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericFinalFieldOverlapsView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+
+namespace DynamicFinalFieldOverlaps {
+
+}  // namespace DynamicFinalFieldOverlaps
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericDynamicFinalFieldOverlapsView;
+
+template <class Storage>
+class GenericDynamicFinalFieldOverlapsView final {
+ public:
+  GenericDynamicFinalFieldOverlapsView() : backing_() {}
+  explicit GenericDynamicFinalFieldOverlapsView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericDynamicFinalFieldOverlapsView(
+      const GenericDynamicFinalFieldOverlapsView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericDynamicFinalFieldOverlapsView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericDynamicFinalFieldOverlapsView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericDynamicFinalFieldOverlapsView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericDynamicFinalFieldOverlapsView<Storage> &operator=(
+      const GenericDynamicFinalFieldOverlapsView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_a().Known()) return false;
+    if (has_a().ValueOrDefault() && !a().Ok()) return false;
+
+
+    if (!has_b().Known()) return false;
+    if (has_b().ValueOrDefault() && !b().Ok()) return false;
+
+
+    if (!has_c().Known()) return false;
+    if (has_c().ValueOrDefault() && !c().Ok()) return false;
+
+
+    if (!has_d().Known()) return false;
+    if (has_d().ValueOrDefault() && !d().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericDynamicFinalFieldOverlapsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_a().Known()) return false;
+    if (!emboss_reserved_local_other.has_a().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        !has_a().ValueOrDefault())
+      return false;
+    if (has_a().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        has_a().ValueOrDefault() &&
+        !a().Equals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (!has_b().Known()) return false;
+    if (!emboss_reserved_local_other.has_b().Known()) return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        !has_b().ValueOrDefault())
+      return false;
+    if (has_b().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_b().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        has_b().ValueOrDefault() &&
+        !b().Equals(emboss_reserved_local_other.b()))
+      return false;
+
+
+
+    if (!has_c().Known()) return false;
+    if (!emboss_reserved_local_other.has_c().Known()) return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOrDefault() &&
+        !has_c().ValueOrDefault())
+      return false;
+    if (has_c().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_c().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOrDefault() &&
+        has_c().ValueOrDefault() &&
+        !c().Equals(emboss_reserved_local_other.c()))
+      return false;
+
+
+
+    if (!has_d().Known()) return false;
+    if (!emboss_reserved_local_other.has_d().Known()) return false;
+
+    if (emboss_reserved_local_other.has_d().ValueOrDefault() &&
+        !has_d().ValueOrDefault())
+      return false;
+    if (has_d().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_d().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_d().ValueOrDefault() &&
+        has_d().ValueOrDefault() &&
+        !d().Equals(emboss_reserved_local_other.d()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericDynamicFinalFieldOverlapsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        !has_a().ValueOr(false))
+      return false;
+    if (has_a().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        has_a().ValueOr(false) &&
+        !a().UncheckedEquals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        !has_b().ValueOr(false))
+      return false;
+    if (has_b().ValueOr(false) &&
+        !emboss_reserved_local_other.has_b().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        has_b().ValueOr(false) &&
+        !b().UncheckedEquals(emboss_reserved_local_other.b()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_c().ValueOr(false) &&
+        !has_c().ValueOr(false))
+      return false;
+    if (has_c().ValueOr(false) &&
+        !emboss_reserved_local_other.has_c().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOr(false) &&
+        has_c().ValueOr(false) &&
+        !c().UncheckedEquals(emboss_reserved_local_other.c()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_d().ValueOr(false) &&
+        !has_d().ValueOr(false))
+      return false;
+    if (has_d().ValueOr(false) &&
+        !emboss_reserved_local_other.has_d().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_d().ValueOr(false) &&
+        has_d().ValueOr(false) &&
+        !d().UncheckedEquals(emboss_reserved_local_other.d()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericDynamicFinalFieldOverlapsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericDynamicFinalFieldOverlapsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericDynamicFinalFieldOverlapsView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "a") {
+        if (!a().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "b") {
+        if (!b().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "c") {
+        if (!c().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "d") {
+        if (!d().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_a().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a().IsAggregate() || a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a: ");
+        a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a().IsAggregate() && !a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a: UNREADABLE\n");
+      }
+    }
+
+    if (has_b().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b().IsAggregate() || b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("b: ");
+        b().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !b().IsAggregate() && !b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b: UNREADABLE\n");
+      }
+    }
+
+    if (has_c().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          c().IsAggregate() || c().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("c: ");
+        c().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !c().IsAggregate() && !c().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# c: UNREADABLE\n");
+      }
+    }
+
+    if (has_d().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          d().IsAggregate() || d().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("d: ");
+        d().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !d().IsAggregate() && !d().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# d: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ a() const;
+  ::emboss::support::Maybe<bool> has_a() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 9>>, 8>>
+
+ b() const;
+  ::emboss::support::Maybe<bool> has_b() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 16>>
+
+ c() const;
+  ::emboss::support::Maybe<bool> has_c() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+ d() const;
+  ::emboss::support::Maybe<bool> has_d() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericDynamicFinalFieldOverlapsView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.a();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_5, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_6, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_8 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)), emboss_reserved_local_subexpr_4, emboss_reserved_local_subexpr_7);
+
+      return emboss_reserved_local_subexpr_8;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericDynamicFinalFieldOverlapsView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericDynamicFinalFieldOverlapsView;
+};
+using DynamicFinalFieldOverlapsView =
+    GenericDynamicFinalFieldOverlapsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using DynamicFinalFieldOverlapsWriter =
+    GenericDynamicFinalFieldOverlapsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericDynamicFinalFieldOverlapsView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericDynamicFinalFieldOverlapsView<
+    GenericDynamicFinalFieldOverlapsView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericDynamicFinalFieldOverlapsView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeDynamicFinalFieldOverlapsView( T &&emboss_reserved_local_arg) {
+  return GenericDynamicFinalFieldOverlapsView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericDynamicFinalFieldOverlapsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeDynamicFinalFieldOverlapsView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericDynamicFinalFieldOverlapsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericDynamicFinalFieldOverlapsView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedDynamicFinalFieldOverlapsView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericDynamicFinalFieldOverlapsView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace DynamicFieldDependsOnLaterField {
+
+}  // namespace DynamicFieldDependsOnLaterField
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericDynamicFieldDependsOnLaterFieldView;
+
+template <class Storage>
+class GenericDynamicFieldDependsOnLaterFieldView final {
+ public:
+  GenericDynamicFieldDependsOnLaterFieldView() : backing_() {}
+  explicit GenericDynamicFieldDependsOnLaterFieldView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericDynamicFieldDependsOnLaterFieldView(
+      const GenericDynamicFieldDependsOnLaterFieldView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericDynamicFieldDependsOnLaterFieldView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericDynamicFieldDependsOnLaterFieldView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericDynamicFieldDependsOnLaterFieldView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericDynamicFieldDependsOnLaterFieldView<Storage> &operator=(
+      const GenericDynamicFieldDependsOnLaterFieldView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_a().Known()) return false;
+    if (has_a().ValueOrDefault() && !a().Ok()) return false;
+
+
+    if (!has_b().Known()) return false;
+    if (has_b().ValueOrDefault() && !b().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericDynamicFieldDependsOnLaterFieldView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_a().Known()) return false;
+    if (!emboss_reserved_local_other.has_a().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        !has_a().ValueOrDefault())
+      return false;
+    if (has_a().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        has_a().ValueOrDefault() &&
+        !a().Equals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (!has_b().Known()) return false;
+    if (!emboss_reserved_local_other.has_b().Known()) return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        !has_b().ValueOrDefault())
+      return false;
+    if (has_b().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_b().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        has_b().ValueOrDefault() &&
+        !b().Equals(emboss_reserved_local_other.b()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericDynamicFieldDependsOnLaterFieldView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        !has_a().ValueOr(false))
+      return false;
+    if (has_a().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        has_a().ValueOr(false) &&
+        !a().UncheckedEquals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        !has_b().ValueOr(false))
+      return false;
+    if (has_b().ValueOr(false) &&
+        !emboss_reserved_local_other.has_b().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        has_b().ValueOr(false) &&
+        !b().UncheckedEquals(emboss_reserved_local_other.b()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericDynamicFieldDependsOnLaterFieldView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericDynamicFieldDependsOnLaterFieldView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericDynamicFieldDependsOnLaterFieldView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "a") {
+        if (!a().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "b") {
+        if (!b().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_a().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a().IsAggregate() || a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a: ");
+        a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a().IsAggregate() && !a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a: UNREADABLE\n");
+      }
+    }
+
+    if (has_b().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b().IsAggregate() || b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("b: ");
+        b().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !b().IsAggregate() && !b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 8>>
+
+ a() const;
+  ::emboss::support::Maybe<bool> has_a() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+ b() const;
+  ::emboss::support::Maybe<bool> has_b() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericDynamicFieldDependsOnLaterFieldView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.a();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_4, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), emboss_reserved_local_subexpr_5, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
+
+      return emboss_reserved_local_subexpr_6;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericDynamicFieldDependsOnLaterFieldView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericDynamicFieldDependsOnLaterFieldView;
+};
+using DynamicFieldDependsOnLaterFieldView =
+    GenericDynamicFieldDependsOnLaterFieldView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using DynamicFieldDependsOnLaterFieldWriter =
+    GenericDynamicFieldDependsOnLaterFieldView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericDynamicFieldDependsOnLaterFieldView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericDynamicFieldDependsOnLaterFieldView<
+    GenericDynamicFieldDependsOnLaterFieldView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericDynamicFieldDependsOnLaterFieldView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeDynamicFieldDependsOnLaterFieldView( T &&emboss_reserved_local_arg) {
+  return GenericDynamicFieldDependsOnLaterFieldView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericDynamicFieldDependsOnLaterFieldView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeDynamicFieldDependsOnLaterFieldView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericDynamicFieldDependsOnLaterFieldView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericDynamicFieldDependsOnLaterFieldView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedDynamicFieldDependsOnLaterFieldView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericDynamicFieldDependsOnLaterFieldView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace DynamicFieldDoesNotAffectSize {
+
+}  // namespace DynamicFieldDoesNotAffectSize
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericDynamicFieldDoesNotAffectSizeView;
+
+template <class Storage>
+class GenericDynamicFieldDoesNotAffectSizeView final {
+ public:
+  GenericDynamicFieldDoesNotAffectSizeView() : backing_() {}
+  explicit GenericDynamicFieldDoesNotAffectSizeView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericDynamicFieldDoesNotAffectSizeView(
+      const GenericDynamicFieldDoesNotAffectSizeView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericDynamicFieldDoesNotAffectSizeView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericDynamicFieldDoesNotAffectSizeView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericDynamicFieldDoesNotAffectSizeView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericDynamicFieldDoesNotAffectSizeView<Storage> &operator=(
+      const GenericDynamicFieldDoesNotAffectSizeView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_a().Known()) return false;
+    if (has_a().ValueOrDefault() && !a().Ok()) return false;
+
+
+    if (!has_b().Known()) return false;
+    if (has_b().ValueOrDefault() && !b().Ok()) return false;
+
+
+    if (!has_c().Known()) return false;
+    if (has_c().ValueOrDefault() && !c().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericDynamicFieldDoesNotAffectSizeView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_a().Known()) return false;
+    if (!emboss_reserved_local_other.has_a().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        !has_a().ValueOrDefault())
+      return false;
+    if (has_a().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        has_a().ValueOrDefault() &&
+        !a().Equals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (!has_b().Known()) return false;
+    if (!emboss_reserved_local_other.has_b().Known()) return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        !has_b().ValueOrDefault())
+      return false;
+    if (has_b().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_b().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        has_b().ValueOrDefault() &&
+        !b().Equals(emboss_reserved_local_other.b()))
+      return false;
+
+
+
+    if (!has_c().Known()) return false;
+    if (!emboss_reserved_local_other.has_c().Known()) return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOrDefault() &&
+        !has_c().ValueOrDefault())
+      return false;
+    if (has_c().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_c().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOrDefault() &&
+        has_c().ValueOrDefault() &&
+        !c().Equals(emboss_reserved_local_other.c()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericDynamicFieldDoesNotAffectSizeView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        !has_a().ValueOr(false))
+      return false;
+    if (has_a().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        has_a().ValueOr(false) &&
+        !a().UncheckedEquals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        !has_b().ValueOr(false))
+      return false;
+    if (has_b().ValueOr(false) &&
+        !emboss_reserved_local_other.has_b().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        has_b().ValueOr(false) &&
+        !b().UncheckedEquals(emboss_reserved_local_other.b()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_c().ValueOr(false) &&
+        !has_c().ValueOr(false))
+      return false;
+    if (has_c().ValueOr(false) &&
+        !emboss_reserved_local_other.has_c().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOr(false) &&
+        has_c().ValueOr(false) &&
+        !c().UncheckedEquals(emboss_reserved_local_other.c()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericDynamicFieldDoesNotAffectSizeView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericDynamicFieldDoesNotAffectSizeView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericDynamicFieldDoesNotAffectSizeView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "a") {
+        if (!a().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "b") {
+        if (!b().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "c") {
+        if (!c().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_a().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a().IsAggregate() || a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a: ");
+        a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a().IsAggregate() && !a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a: UNREADABLE\n");
+      }
+    }
+
+    if (has_b().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b().IsAggregate() || b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("b: ");
+        b().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !b().IsAggregate() && !b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b: UNREADABLE\n");
+      }
+    }
+
+    if (has_c().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          c().IsAggregate() || c().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("c: ");
+        c().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !c().IsAggregate() && !c().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# c: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ a() const;
+  ::emboss::support::Maybe<bool> has_a() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+ b() const;
+  ::emboss::support::Maybe<bool> has_b() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 255>>, 8>>
+
+ c() const;
+  ::emboss::support::Maybe<bool> has_c() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericDynamicFieldDoesNotAffectSizeView;
+};
+using DynamicFieldDoesNotAffectSizeView =
+    GenericDynamicFieldDoesNotAffectSizeView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using DynamicFieldDoesNotAffectSizeWriter =
+    GenericDynamicFieldDoesNotAffectSizeView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericDynamicFieldDoesNotAffectSizeView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericDynamicFieldDoesNotAffectSizeView<
+    GenericDynamicFieldDoesNotAffectSizeView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericDynamicFieldDoesNotAffectSizeView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeDynamicFieldDoesNotAffectSizeView( T &&emboss_reserved_local_arg) {
+  return GenericDynamicFieldDoesNotAffectSizeView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericDynamicFieldDoesNotAffectSizeView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeDynamicFieldDoesNotAffectSizeView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericDynamicFieldDoesNotAffectSizeView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericDynamicFieldDoesNotAffectSizeView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedDynamicFieldDoesNotAffectSizeView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericDynamicFieldDoesNotAffectSizeView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace Message {
+
+}  // namespace Message
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericMessageView<Storage>::header_length()
+    const {
+
+  if ( has_header_length().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericMessageView<Storage>::has_header_length() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericMessageView<Storage>::message_length()
+    const {
+
+  if ( has_message_length().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericMessageView<Storage>::has_message_length() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 2>, 1,
+    8 >
+
+ GenericMessageView<Storage>::padding()
+    const {
+
+  if ( has_padding().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = header_length();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)));
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_3;
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 2>, 1,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 2>, 1,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericMessageView<Storage>::has_padding() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/1, 0>, 1,
+    8 >
+
+ GenericMessageView<Storage>::message()
+    const {
+
+  if ( has_message().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = header_length();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_3 = message_length();
+    const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_4;
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_2;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/1, 0>, 1,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/1, 0>, 1,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericMessageView<Storage>::has_message() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 32>>
+
+ GenericMessageView<Storage>::crc32()
+    const {
+
+  if ( has_crc32().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = header_length();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_3 = message_length();
+    const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_4);
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_5;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericMessageView<Storage>::has_crc32() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericMessageView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericMessageView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericMessageView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericMessageView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Message {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(514LL)).ValueOrDefault();
+}
+}  // namespace Message
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericMessageView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Message::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericMessageView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Message::MaxSizeInBytes();
+}
+
+namespace Message {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace Message
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericMessageView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Message::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericMessageView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Message::MinSizeInBytes();
+}
+namespace Image {
+
+}  // namespace Image
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericImageView<Storage>::size()
+    const {
+
+  if ( has_size().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericImageView<Storage>::has_size() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::support::GenericArrayView<
+    typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/15, 0>::template OffsetStorageType</**/3, 0>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/15, 0>::template OffsetStorageType</**/3, 0>, 1,
+    8 >
+
+, typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/15, 0>, 3,
+    8 >
+
+, typename Storage::template OffsetStorageType</**/0, 1>, 15,
+    8 >
+
+ GenericImageView<Storage>::pixels()
+    const {
+
+  if ( has_pixels().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = size();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Product</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(15LL)), emboss_reserved_local_subexpr_2);
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_3;
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::support::GenericArrayView<
+    typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/15, 0>::template OffsetStorageType</**/3, 0>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/15, 0>::template OffsetStorageType</**/3, 0>, 1,
+    8 >
+
+, typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/15, 0>, 3,
+    8 >
+
+, typename Storage::template OffsetStorageType</**/0, 1>, 15,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::support::GenericArrayView<
+    typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/15, 0>::template OffsetStorageType</**/3, 0>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/15, 0>::template OffsetStorageType</**/3, 0>, 1,
+    8 >
+
+, typename Storage::template OffsetStorageType</**/0, 1>::template OffsetStorageType</**/15, 0>, 3,
+    8 >
+
+, typename Storage::template OffsetStorageType</**/0, 1>, 15,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericImageView<Storage>::has_pixels() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericImageView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericImageView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericImageView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericImageView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Image {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3826LL)).ValueOrDefault();
+}
+}  // namespace Image
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericImageView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Image::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericImageView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Image::MaxSizeInBytes();
+}
+
+namespace Image {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace Image
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericImageView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Image::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericImageView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Image::MinSizeInBytes();
+}
+namespace TwoRegions {
+
+}  // namespace TwoRegions
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 8>>
+
+ GenericTwoRegionsView<Storage>::b_end()
+    const {
+
+  if ( has_b_end().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   3>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericTwoRegionsView<Storage>::has_b_end() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ GenericTwoRegionsView<Storage>::b_start()
+    const {
+
+  if ( has_b_start().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericTwoRegionsView<Storage>::has_b_start() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericTwoRegionsView<Storage>::a_size()
+    const {
+
+  if ( has_a_size().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericTwoRegionsView<Storage>::has_a_size() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericTwoRegionsView<Storage>::a_start()
+    const {
+
+  if ( has_a_start().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericTwoRegionsView<Storage>::has_a_start() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/1, 0>, 1,
+    8 >
+
+ GenericTwoRegionsView<Storage>::region_a()
+    const {
+
+  if ( has_region_a().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = a_start();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_3 = a_size();
+    const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_4;
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_2;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/1, 0>, 1,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/1, 0>, 1,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericTwoRegionsView<Storage>::has_region_a() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/1, 0>, 1,
+    8 >
+
+ GenericTwoRegionsView<Storage>::region_b()
+    const {
+
+  if ( has_region_b().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = b_start();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_3 = b_end();
+    const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_4, emboss_reserved_local_subexpr_2);
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_5;
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_2;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/1, 0>, 1,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/1, 0>, 1,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericTwoRegionsView<Storage>::has_region_b() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericTwoRegionsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericTwoRegionsView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericTwoRegionsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericTwoRegionsView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace TwoRegions {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(510LL)).ValueOrDefault();
+}
+}  // namespace TwoRegions
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericTwoRegionsView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return TwoRegions::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericTwoRegionsView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return TwoRegions::MaxSizeInBytes();
+}
+
+namespace TwoRegions {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace TwoRegions
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericTwoRegionsView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return TwoRegions::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericTwoRegionsView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return TwoRegions::MinSizeInBytes();
+}
+namespace MultipliedSize {
+
+}  // namespace MultipliedSize
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericMultipliedSizeView<Storage>::width()
+    const {
+
+  if ( has_width().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericMultipliedSizeView<Storage>::has_width() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericMultipliedSizeView<Storage>::height()
+    const {
+
+  if ( has_height().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericMultipliedSizeView<Storage>::has_height() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 2>, 1,
+    8 >
+
+ GenericMultipliedSizeView<Storage>::data()
+    const {
+
+  if ( has_data().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = width();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_3 = height();
+    const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Product</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_4);
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_5;
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 2>, 1,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 2>, 1,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericMultipliedSizeView<Storage>::has_data() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericMultipliedSizeView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericMultipliedSizeView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericMultipliedSizeView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericMultipliedSizeView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace MultipliedSize {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(65027LL)).ValueOrDefault();
+}
+}  // namespace MultipliedSize
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericMultipliedSizeView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return MultipliedSize::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericMultipliedSizeView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return MultipliedSize::MaxSizeInBytes();
+}
+
+namespace MultipliedSize {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace MultipliedSize
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericMultipliedSizeView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return MultipliedSize::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericMultipliedSizeView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return MultipliedSize::MinSizeInBytes();
+}
+namespace NegativeTermsInSizes {
+
+}  // namespace NegativeTermsInSizes
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericNegativeTermsInSizesView<Storage>::a()
+    const {
+
+  if ( has_a().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNegativeTermsInSizesView<Storage>::has_a() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericNegativeTermsInSizesView<Storage>::b()
+    const {
+
+  if ( has_b().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNegativeTermsInSizesView<Storage>::has_b() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ GenericNegativeTermsInSizesView<Storage>::c()
+    const {
+
+  if ( has_c().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNegativeTermsInSizesView<Storage>::has_c() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+ GenericNegativeTermsInSizesView<Storage>::a_minus_b()
+    const {
+
+  if ( has_a_minus_b().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = a();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_3 = b();
+    const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_4);
+    const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_5, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)));
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_6;
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   3>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNegativeTermsInSizesView<Storage>::has_a_minus_b() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+ GenericNegativeTermsInSizesView<Storage>::a_minus_2b()
+    const {
+
+  if ( has_a_minus_2b().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = a();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_3 = b();
+    const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Product</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), emboss_reserved_local_subexpr_4);
+    const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_5);
+    const auto emboss_reserved_local_subexpr_7 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_6, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)));
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_7;
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   3>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNegativeTermsInSizesView<Storage>::has_a_minus_2b() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+ GenericNegativeTermsInSizesView<Storage>::a_minus_b_minus_c()
+    const {
+
+  if ( has_a_minus_b_minus_c().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = a();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_3 = b();
+    const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_4);
+    const auto emboss_reserved_local_subexpr_6 = c();
+    const auto emboss_reserved_local_subexpr_7 = (emboss_reserved_local_subexpr_6.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_6.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_8 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_5, emboss_reserved_local_subexpr_7);
+    const auto emboss_reserved_local_subexpr_9 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_8, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)));
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_9;
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   3>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNegativeTermsInSizesView<Storage>::has_a_minus_b_minus_c() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+ GenericNegativeTermsInSizesView<Storage>::ten_minus_a()
+    const {
+
+  if ( has_ten_minus_a().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = a();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(7LL)), emboss_reserved_local_subexpr_2);
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_3;
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   3>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNegativeTermsInSizesView<Storage>::has_ten_minus_a() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+ GenericNegativeTermsInSizesView<Storage>::a_minus_2c()
+    const {
+
+  if ( has_a_minus_2c().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = a();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_3 = c();
+    const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Product</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), emboss_reserved_local_subexpr_4);
+    const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_5);
+    const auto emboss_reserved_local_subexpr_7 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_6, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)));
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_7;
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   3>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNegativeTermsInSizesView<Storage>::has_a_minus_2c() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+ GenericNegativeTermsInSizesView<Storage>::a_minus_c()
+    const {
+
+  if ( has_a_minus_c().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = a();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_3 = c();
+    const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_4);
+    const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_5, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)));
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_6;
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   3>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNegativeTermsInSizesView<Storage>::has_a_minus_c() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericNegativeTermsInSizesView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericNegativeTermsInSizesView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericNegativeTermsInSizesView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNegativeTermsInSizesView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace NegativeTermsInSizes {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(255LL)).ValueOrDefault();
+}
+}  // namespace NegativeTermsInSizes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericNegativeTermsInSizesView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return NegativeTermsInSizes::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericNegativeTermsInSizesView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return NegativeTermsInSizes::MaxSizeInBytes();
+}
+
+namespace NegativeTermsInSizes {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace NegativeTermsInSizes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericNegativeTermsInSizesView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return NegativeTermsInSizes::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericNegativeTermsInSizesView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return NegativeTermsInSizes::MinSizeInBytes();
+}
+namespace NegativeTermInLocation {
+
+}  // namespace NegativeTermInLocation
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericNegativeTermInLocationView<Storage>::a()
+    const {
+
+  if ( has_a().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNegativeTermInLocationView<Storage>::has_a() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+ GenericNegativeTermInLocationView<Storage>::b()
+    const {
+
+  if ( has_b().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = a();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)), emboss_reserved_local_subexpr_2);
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_3;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNegativeTermInLocationView<Storage>::has_b() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericNegativeTermInLocationView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericNegativeTermInLocationView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericNegativeTermInLocationView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNegativeTermInLocationView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace NegativeTermInLocation {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(11LL)).ValueOrDefault();
+}
+}  // namespace NegativeTermInLocation
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericNegativeTermInLocationView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return NegativeTermInLocation::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericNegativeTermInLocationView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return NegativeTermInLocation::MaxSizeInBytes();
+}
+
+namespace NegativeTermInLocation {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace NegativeTermInLocation
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericNegativeTermInLocationView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return NegativeTermInLocation::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericNegativeTermInLocationView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return NegativeTermInLocation::MinSizeInBytes();
+}
+namespace ChainedSize {
+
+}  // namespace ChainedSize
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericChainedSizeView<Storage>::a()
+    const {
+
+  if ( has_a().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericChainedSizeView<Storage>::has_a() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+ GenericChainedSizeView<Storage>::b()
+    const {
+
+  if ( has_b().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = a();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_2;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericChainedSizeView<Storage>::has_b() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+ GenericChainedSizeView<Storage>::c()
+    const {
+
+  if ( has_c().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = b();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_2;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericChainedSizeView<Storage>::has_c() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+ GenericChainedSizeView<Storage>::d()
+    const {
+
+  if ( has_d().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = c();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_2;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericChainedSizeView<Storage>::has_d() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericChainedSizeView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericChainedSizeView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericChainedSizeView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericChainedSizeView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace ChainedSize {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(256LL)).ValueOrDefault();
+}
+}  // namespace ChainedSize
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericChainedSizeView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return ChainedSize::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericChainedSizeView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return ChainedSize::MaxSizeInBytes();
+}
+
+namespace ChainedSize {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace ChainedSize
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericChainedSizeView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return ChainedSize::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericChainedSizeView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return ChainedSize::MinSizeInBytes();
+}
+namespace FinalFieldOverlaps {
+
+}  // namespace FinalFieldOverlaps
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericFinalFieldOverlapsView<Storage>::a()
+    const {
+
+  if ( has_a().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericFinalFieldOverlapsView<Storage>::has_a() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 32>>
+
+ GenericFinalFieldOverlapsView<Storage>::b()
+    const {
+
+  if ( has_b().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericFinalFieldOverlapsView<Storage>::has_b() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 16>>
+
+ GenericFinalFieldOverlapsView<Storage>::c()
+    const {
+
+  if ( has_c().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 16>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   3>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 16>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericFinalFieldOverlapsView<Storage>::has_c() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace FinalFieldOverlaps {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)).ValueOrDefault();
+}
+}  // namespace FinalFieldOverlaps
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFinalFieldOverlapsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return FinalFieldOverlaps::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFinalFieldOverlapsView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return FinalFieldOverlaps::IntrinsicSizeInBytes();
+}
+
+namespace FinalFieldOverlaps {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)).ValueOrDefault();
+}
+}  // namespace FinalFieldOverlaps
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFinalFieldOverlapsView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return FinalFieldOverlaps::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFinalFieldOverlapsView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return FinalFieldOverlaps::MaxSizeInBytes();
+}
+
+namespace FinalFieldOverlaps {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)).ValueOrDefault();
+}
+}  // namespace FinalFieldOverlaps
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFinalFieldOverlapsView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return FinalFieldOverlaps::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFinalFieldOverlapsView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return FinalFieldOverlaps::MinSizeInBytes();
+}
+namespace DynamicFinalFieldOverlaps {
+
+}  // namespace DynamicFinalFieldOverlaps
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericDynamicFinalFieldOverlapsView<Storage>::a()
+    const {
+
+  if ( has_a().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericDynamicFinalFieldOverlapsView<Storage>::has_a() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 9>>, 8>>
+
+ GenericDynamicFinalFieldOverlapsView<Storage>::b()
+    const {
+
+  if ( has_b().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(9LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 9>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   9>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 9>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericDynamicFinalFieldOverlapsView<Storage>::has_b() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 16>>
+
+ GenericDynamicFinalFieldOverlapsView<Storage>::c()
+    const {
+
+  if ( has_c().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = a();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_2;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 16>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 16>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericDynamicFinalFieldOverlapsView<Storage>::has_c() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+ GenericDynamicFinalFieldOverlapsView<Storage>::d()
+    const {
+
+  if ( has_d().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = a();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_3;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericDynamicFinalFieldOverlapsView<Storage>::has_d() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericDynamicFinalFieldOverlapsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericDynamicFinalFieldOverlapsView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericDynamicFinalFieldOverlapsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericDynamicFinalFieldOverlapsView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace DynamicFinalFieldOverlaps {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(257LL)).ValueOrDefault();
+}
+}  // namespace DynamicFinalFieldOverlaps
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericDynamicFinalFieldOverlapsView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return DynamicFinalFieldOverlaps::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericDynamicFinalFieldOverlapsView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return DynamicFinalFieldOverlaps::MaxSizeInBytes();
+}
+
+namespace DynamicFinalFieldOverlaps {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)).ValueOrDefault();
+}
+}  // namespace DynamicFinalFieldOverlaps
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericDynamicFinalFieldOverlapsView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return DynamicFinalFieldOverlaps::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericDynamicFinalFieldOverlapsView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return DynamicFinalFieldOverlaps::MinSizeInBytes();
+}
+namespace DynamicFieldDependsOnLaterField {
+
+}  // namespace DynamicFieldDependsOnLaterField
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 8>>
+
+ GenericDynamicFieldDependsOnLaterFieldView<Storage>::a()
+    const {
+
+  if ( has_a().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   4>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericDynamicFieldDependsOnLaterFieldView<Storage>::has_a() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+ GenericDynamicFieldDependsOnLaterFieldView<Storage>::b()
+    const {
+
+  if ( has_b().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = a();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_3;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericDynamicFieldDependsOnLaterFieldView<Storage>::has_b() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericDynamicFieldDependsOnLaterFieldView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericDynamicFieldDependsOnLaterFieldView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericDynamicFieldDependsOnLaterFieldView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericDynamicFieldDependsOnLaterFieldView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace DynamicFieldDependsOnLaterField {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(257LL)).ValueOrDefault();
+}
+}  // namespace DynamicFieldDependsOnLaterField
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericDynamicFieldDependsOnLaterFieldView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return DynamicFieldDependsOnLaterField::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericDynamicFieldDependsOnLaterFieldView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return DynamicFieldDependsOnLaterField::MaxSizeInBytes();
+}
+
+namespace DynamicFieldDependsOnLaterField {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)).ValueOrDefault();
+}
+}  // namespace DynamicFieldDependsOnLaterField
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericDynamicFieldDependsOnLaterFieldView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return DynamicFieldDependsOnLaterField::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericDynamicFieldDependsOnLaterFieldView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return DynamicFieldDependsOnLaterField::MinSizeInBytes();
+}
+namespace DynamicFieldDoesNotAffectSize {
+
+}  // namespace DynamicFieldDoesNotAffectSize
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericDynamicFieldDoesNotAffectSizeView<Storage>::a()
+    const {
+
+  if ( has_a().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericDynamicFieldDoesNotAffectSizeView<Storage>::has_a() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+ GenericDynamicFieldDoesNotAffectSizeView<Storage>::b()
+    const {
+
+  if ( has_b().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = a();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_2;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericDynamicFieldDoesNotAffectSizeView<Storage>::has_b() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 255>>, 8>>
+
+ GenericDynamicFieldDoesNotAffectSizeView<Storage>::c()
+    const {
+
+  if ( has_c().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(255LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 255>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   255>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 255>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericDynamicFieldDoesNotAffectSizeView<Storage>::has_c() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace DynamicFieldDoesNotAffectSize {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(256LL)).ValueOrDefault();
+}
+}  // namespace DynamicFieldDoesNotAffectSize
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericDynamicFieldDoesNotAffectSizeView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return DynamicFieldDoesNotAffectSize::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericDynamicFieldDoesNotAffectSizeView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return DynamicFieldDoesNotAffectSize::IntrinsicSizeInBytes();
+}
+
+namespace DynamicFieldDoesNotAffectSize {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(256LL)).ValueOrDefault();
+}
+}  // namespace DynamicFieldDoesNotAffectSize
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericDynamicFieldDoesNotAffectSizeView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return DynamicFieldDoesNotAffectSize::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericDynamicFieldDoesNotAffectSizeView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return DynamicFieldDoesNotAffectSize::MaxSizeInBytes();
+}
+
+namespace DynamicFieldDoesNotAffectSize {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(256LL)).ValueOrDefault();
+}
+}  // namespace DynamicFieldDoesNotAffectSize
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericDynamicFieldDoesNotAffectSizeView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return DynamicFieldDoesNotAffectSize::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericDynamicFieldDoesNotAffectSizeView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return DynamicFieldDoesNotAffectSize::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_DYNAMIC_SIZE_EMB_H_
+
diff --git a/testdata/golden_cpp/enum.emb.h b/testdata/golden_cpp/enum.emb.h
new file mode 100644
index 0000000..f056862
--- /dev/null
+++ b/testdata/golden_cpp/enum.emb.h
@@ -0,0 +1,3642 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_ENUM_EMB_H_
+#define TESTDATA_ENUM_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace Constants {
+
+}  // namespace Constants
+
+
+template <class Storage>
+class GenericConstantsView;
+
+enum class Kind : ::std::uint64_t;
+
+enum class Signed : ::std::int64_t;
+
+enum class OnlyShortValues : ::std::uint64_t;
+
+enum class OnlyShortSignedValues : ::std::int64_t;
+
+enum class ExplicitlySigned : ::std::int64_t;
+
+enum class ExplicitlySized64 : ::std::uint64_t;
+
+enum class ExplicitlySized32 : ::std::uint32_t;
+
+enum class ExplicitlySized16 : ::std::uint16_t;
+
+enum class ExplicitlySized8 : ::std::uint8_t;
+
+enum class ExplicitlySized12 : ::std::uint16_t;
+
+enum class ExplicitlySizedAndSigned : ::std::int32_t;
+
+namespace ManifestEntry {
+namespace EmbossReservedAnonymousField1 {
+
+}  // namespace EmbossReservedAnonymousField1
+
+
+template <class Storage>
+class GenericEmbossReservedAnonymousField1View;
+
+
+}  // namespace ManifestEntry
+
+
+template <class Storage>
+class GenericManifestEntryView;
+
+namespace StructContainingEnum {
+enum class Status : ::std::uint64_t;
+
+
+}  // namespace StructContainingEnum
+
+
+template <class Storage>
+class GenericStructContainingEnumView;
+
+
+
+
+
+
+namespace Constants {
+
+}  // namespace Constants
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericConstantsView;
+
+template <class Storage>
+class GenericConstantsView final {
+ public:
+  GenericConstantsView() : backing_() {}
+  explicit GenericConstantsView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericConstantsView(
+      const GenericConstantsView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericConstantsView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericConstantsView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericConstantsView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericConstantsView<Storage> &operator=(
+      const GenericConstantsView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_sprocket().Known()) return false;
+    if (has_sprocket().ValueOrDefault() && !sprocket().Ok()) return false;
+
+
+    if (!has_geegaw().Known()) return false;
+    if (has_geegaw().ValueOrDefault() && !geegaw().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericConstantsView<OtherStorage> emboss_reserved_local_other) const {
+     return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericConstantsView<OtherStorage> emboss_reserved_local_other) const {
+     return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericConstantsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericConstantsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericConstantsView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_sprocket().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          sprocket().IsAggregate() || sprocket().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# sprocket: ");
+        sprocket().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# sprocket: UNREADABLE\n");
+      }
+    }
+
+    if (has_geegaw().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          geegaw().IsAggregate() || geegaw().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# geegaw: ");
+        geegaw().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# geegaw: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  class EmbossReservedVirtualSprocketView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedVirtualSprocketView() {}
+    EmbossReservedVirtualSprocketView(const EmbossReservedVirtualSprocketView &) = default;
+    EmbossReservedVirtualSprocketView(EmbossReservedVirtualSprocketView &&) = default;
+    EmbossReservedVirtualSprocketView &operator=(const EmbossReservedVirtualSprocketView &) =
+        default;
+    EmbossReservedVirtualSprocketView &operator=(EmbossReservedVirtualSprocketView &&) =
+        default;
+    ~EmbossReservedVirtualSprocketView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedVirtualSprocketView sprocket() {
+    return EmbossReservedVirtualSprocketView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_sprocket() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedVirtualGeegawView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedVirtualGeegawView() {}
+    EmbossReservedVirtualGeegawView(const EmbossReservedVirtualGeegawView &) = default;
+    EmbossReservedVirtualGeegawView(EmbossReservedVirtualGeegawView &&) = default;
+    EmbossReservedVirtualGeegawView &operator=(const EmbossReservedVirtualGeegawView &) =
+        default;
+    EmbossReservedVirtualGeegawView &operator=(EmbossReservedVirtualGeegawView &&) =
+        default;
+    ~EmbossReservedVirtualGeegawView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedVirtualGeegawView geegaw() {
+    return EmbossReservedVirtualGeegawView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_geegaw() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericConstantsView;
+};
+using ConstantsView =
+    GenericConstantsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ConstantsWriter =
+    GenericConstantsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericConstantsView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericConstantsView<
+    GenericConstantsView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericConstantsView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeConstantsView( T &&emboss_reserved_local_arg) {
+  return GenericConstantsView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericConstantsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeConstantsView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericConstantsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericConstantsView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedConstantsView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericConstantsView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+enum class Kind : ::std::uint64_t {
+  WIDGET = static_cast</**/::std::int32_t>(0LL),
+  SPROCKET = static_cast</**/::std::int32_t>(1LL),
+  GEEGAW = static_cast</**/::std::int32_t>(2LL),
+  COMPUTED = static_cast</**/::std::int32_t>(3LL),
+  LARGE_VALUE = static_cast</**/::std::int32_t>(2000LL),
+  DUPLICATE_LARGE_VALUE = static_cast</**/::std::int32_t>(2000LL),
+  MAX32BIT = static_cast</**/::std::uint32_t>(4294967295ULL),
+  MAX64BIT = static_cast</**/::std::uint64_t>(18446744073709551615ULL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<Kind> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   Kind *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("WIDGET", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Kind::WIDGET;
+      return true;
+    }
+
+    if (!strcmp("SPROCKET", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Kind::SPROCKET;
+      return true;
+    }
+
+    if (!strcmp("GEEGAW", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Kind::GEEGAW;
+      return true;
+    }
+
+    if (!strcmp("COMPUTED", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Kind::COMPUTED;
+      return true;
+    }
+
+    if (!strcmp("LARGE_VALUE", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Kind::LARGE_VALUE;
+      return true;
+    }
+
+    if (!strcmp("DUPLICATE_LARGE_VALUE", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Kind::DUPLICATE_LARGE_VALUE;
+      return true;
+    }
+
+    if (!strcmp("MAX32BIT", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Kind::MAX32BIT;
+      return true;
+    }
+
+    if (!strcmp("MAX64BIT", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Kind::MAX64BIT;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      Kind emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Kind::WIDGET: return "WIDGET";
+
+      case Kind::SPROCKET: return "SPROCKET";
+
+      case Kind::GEEGAW: return "GEEGAW";
+
+      case Kind::COMPUTED: return "COMPUTED";
+
+      case Kind::LARGE_VALUE: return "LARGE_VALUE";
+
+      case Kind::MAX32BIT: return "MAX32BIT";
+
+      case Kind::MAX64BIT: return "MAX64BIT";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(Kind emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Kind::WIDGET: return true;
+
+      case Kind::SPROCKET: return true;
+
+      case Kind::GEEGAW: return true;
+
+      case Kind::COMPUTED: return true;
+
+      case Kind::LARGE_VALUE: return true;
+
+      case Kind::MAX32BIT: return true;
+
+      case Kind::MAX64BIT: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       Kind emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<Kind>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    Kind *emboss_reserved_local_result) {
+  return EnumTraits<Kind>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    Kind emboss_reserved_local_value) {
+  return EnumTraits<Kind>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(Kind emboss_reserved_local_value) {
+  return EnumTraits<Kind>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    Kind emboss_reserved_local_value) {
+  return EnumTraits<Kind>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+enum class Signed : ::std::int64_t {
+  MIN64BIT = static_cast</**/::std::int64_t>(-9223372036854775807LL - 1),
+  MAX64BIT = static_cast</**/::std::int64_t>(9223372036854775807LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<Signed> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   Signed *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("MIN64BIT", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Signed::MIN64BIT;
+      return true;
+    }
+
+    if (!strcmp("MAX64BIT", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Signed::MAX64BIT;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      Signed emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Signed::MIN64BIT: return "MIN64BIT";
+
+      case Signed::MAX64BIT: return "MAX64BIT";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(Signed emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Signed::MIN64BIT: return true;
+
+      case Signed::MAX64BIT: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       Signed emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<Signed>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    Signed *emboss_reserved_local_result) {
+  return EnumTraits<Signed>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    Signed emboss_reserved_local_value) {
+  return EnumTraits<Signed>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(Signed emboss_reserved_local_value) {
+  return EnumTraits<Signed>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    Signed emboss_reserved_local_value) {
+  return EnumTraits<Signed>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+enum class OnlyShortValues : ::std::uint64_t {
+  ZERO = static_cast</**/::std::int32_t>(0LL),
+  ONE = static_cast</**/::std::int32_t>(1LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<OnlyShortValues> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   OnlyShortValues *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("ZERO", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = OnlyShortValues::ZERO;
+      return true;
+    }
+
+    if (!strcmp("ONE", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = OnlyShortValues::ONE;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      OnlyShortValues emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case OnlyShortValues::ZERO: return "ZERO";
+
+      case OnlyShortValues::ONE: return "ONE";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(OnlyShortValues emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case OnlyShortValues::ZERO: return true;
+
+      case OnlyShortValues::ONE: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       OnlyShortValues emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<OnlyShortValues>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    OnlyShortValues *emboss_reserved_local_result) {
+  return EnumTraits<OnlyShortValues>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    OnlyShortValues emboss_reserved_local_value) {
+  return EnumTraits<OnlyShortValues>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(OnlyShortValues emboss_reserved_local_value) {
+  return EnumTraits<OnlyShortValues>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    OnlyShortValues emboss_reserved_local_value) {
+  return EnumTraits<OnlyShortValues>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+enum class OnlyShortSignedValues : ::std::int64_t {
+  ZERO = static_cast</**/::std::int32_t>(0LL),
+  NEGATIVE_ONE = static_cast</**/::std::int32_t>(-1LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<OnlyShortSignedValues> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   OnlyShortSignedValues *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("ZERO", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = OnlyShortSignedValues::ZERO;
+      return true;
+    }
+
+    if (!strcmp("NEGATIVE_ONE", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = OnlyShortSignedValues::NEGATIVE_ONE;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      OnlyShortSignedValues emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case OnlyShortSignedValues::ZERO: return "ZERO";
+
+      case OnlyShortSignedValues::NEGATIVE_ONE: return "NEGATIVE_ONE";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(OnlyShortSignedValues emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case OnlyShortSignedValues::ZERO: return true;
+
+      case OnlyShortSignedValues::NEGATIVE_ONE: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       OnlyShortSignedValues emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<OnlyShortSignedValues>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    OnlyShortSignedValues *emboss_reserved_local_result) {
+  return EnumTraits<OnlyShortSignedValues>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    OnlyShortSignedValues emboss_reserved_local_value) {
+  return EnumTraits<OnlyShortSignedValues>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(OnlyShortSignedValues emboss_reserved_local_value) {
+  return EnumTraits<OnlyShortSignedValues>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    OnlyShortSignedValues emboss_reserved_local_value) {
+  return EnumTraits<OnlyShortSignedValues>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+enum class ExplicitlySigned : ::std::int64_t {
+  ZERO = static_cast</**/::std::int32_t>(0LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<ExplicitlySigned> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   ExplicitlySigned *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("ZERO", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = ExplicitlySigned::ZERO;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      ExplicitlySigned emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case ExplicitlySigned::ZERO: return "ZERO";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(ExplicitlySigned emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case ExplicitlySigned::ZERO: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       ExplicitlySigned emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<ExplicitlySigned>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    ExplicitlySigned *emboss_reserved_local_result) {
+  return EnumTraits<ExplicitlySigned>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    ExplicitlySigned emboss_reserved_local_value) {
+  return EnumTraits<ExplicitlySigned>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(ExplicitlySigned emboss_reserved_local_value) {
+  return EnumTraits<ExplicitlySigned>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    ExplicitlySigned emboss_reserved_local_value) {
+  return EnumTraits<ExplicitlySigned>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+enum class ExplicitlySized64 : ::std::uint64_t {
+  ZERO = static_cast</**/::std::int32_t>(0LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<ExplicitlySized64> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   ExplicitlySized64 *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("ZERO", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = ExplicitlySized64::ZERO;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      ExplicitlySized64 emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case ExplicitlySized64::ZERO: return "ZERO";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(ExplicitlySized64 emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case ExplicitlySized64::ZERO: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       ExplicitlySized64 emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<ExplicitlySized64>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    ExplicitlySized64 *emboss_reserved_local_result) {
+  return EnumTraits<ExplicitlySized64>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    ExplicitlySized64 emboss_reserved_local_value) {
+  return EnumTraits<ExplicitlySized64>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(ExplicitlySized64 emboss_reserved_local_value) {
+  return EnumTraits<ExplicitlySized64>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    ExplicitlySized64 emboss_reserved_local_value) {
+  return EnumTraits<ExplicitlySized64>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+enum class ExplicitlySized32 : ::std::uint32_t {
+  ZERO = static_cast</**/::std::int32_t>(0LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<ExplicitlySized32> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   ExplicitlySized32 *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("ZERO", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = ExplicitlySized32::ZERO;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      ExplicitlySized32 emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case ExplicitlySized32::ZERO: return "ZERO";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(ExplicitlySized32 emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case ExplicitlySized32::ZERO: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       ExplicitlySized32 emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<ExplicitlySized32>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    ExplicitlySized32 *emboss_reserved_local_result) {
+  return EnumTraits<ExplicitlySized32>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    ExplicitlySized32 emboss_reserved_local_value) {
+  return EnumTraits<ExplicitlySized32>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(ExplicitlySized32 emboss_reserved_local_value) {
+  return EnumTraits<ExplicitlySized32>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    ExplicitlySized32 emboss_reserved_local_value) {
+  return EnumTraits<ExplicitlySized32>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+enum class ExplicitlySized16 : ::std::uint16_t {
+  ZERO = static_cast</**/::std::int32_t>(0LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<ExplicitlySized16> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   ExplicitlySized16 *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("ZERO", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = ExplicitlySized16::ZERO;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      ExplicitlySized16 emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case ExplicitlySized16::ZERO: return "ZERO";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(ExplicitlySized16 emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case ExplicitlySized16::ZERO: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       ExplicitlySized16 emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<ExplicitlySized16>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    ExplicitlySized16 *emboss_reserved_local_result) {
+  return EnumTraits<ExplicitlySized16>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    ExplicitlySized16 emboss_reserved_local_value) {
+  return EnumTraits<ExplicitlySized16>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(ExplicitlySized16 emboss_reserved_local_value) {
+  return EnumTraits<ExplicitlySized16>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    ExplicitlySized16 emboss_reserved_local_value) {
+  return EnumTraits<ExplicitlySized16>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+enum class ExplicitlySized8 : ::std::uint8_t {
+  ZERO = static_cast</**/::std::int32_t>(0LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<ExplicitlySized8> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   ExplicitlySized8 *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("ZERO", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = ExplicitlySized8::ZERO;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      ExplicitlySized8 emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case ExplicitlySized8::ZERO: return "ZERO";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(ExplicitlySized8 emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case ExplicitlySized8::ZERO: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       ExplicitlySized8 emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<ExplicitlySized8>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    ExplicitlySized8 *emboss_reserved_local_result) {
+  return EnumTraits<ExplicitlySized8>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    ExplicitlySized8 emboss_reserved_local_value) {
+  return EnumTraits<ExplicitlySized8>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(ExplicitlySized8 emboss_reserved_local_value) {
+  return EnumTraits<ExplicitlySized8>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    ExplicitlySized8 emboss_reserved_local_value) {
+  return EnumTraits<ExplicitlySized8>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+enum class ExplicitlySized12 : ::std::uint16_t {
+  ZERO = static_cast</**/::std::int32_t>(0LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<ExplicitlySized12> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   ExplicitlySized12 *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("ZERO", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = ExplicitlySized12::ZERO;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      ExplicitlySized12 emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case ExplicitlySized12::ZERO: return "ZERO";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(ExplicitlySized12 emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case ExplicitlySized12::ZERO: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       ExplicitlySized12 emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<ExplicitlySized12>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    ExplicitlySized12 *emboss_reserved_local_result) {
+  return EnumTraits<ExplicitlySized12>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    ExplicitlySized12 emboss_reserved_local_value) {
+  return EnumTraits<ExplicitlySized12>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(ExplicitlySized12 emboss_reserved_local_value) {
+  return EnumTraits<ExplicitlySized12>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    ExplicitlySized12 emboss_reserved_local_value) {
+  return EnumTraits<ExplicitlySized12>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+enum class ExplicitlySizedAndSigned : ::std::int32_t {
+  ZERO = static_cast</**/::std::int32_t>(0LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<ExplicitlySizedAndSigned> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   ExplicitlySizedAndSigned *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("ZERO", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = ExplicitlySizedAndSigned::ZERO;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      ExplicitlySizedAndSigned emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case ExplicitlySizedAndSigned::ZERO: return "ZERO";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(ExplicitlySizedAndSigned emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case ExplicitlySizedAndSigned::ZERO: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       ExplicitlySizedAndSigned emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<ExplicitlySizedAndSigned>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    ExplicitlySizedAndSigned *emboss_reserved_local_result) {
+  return EnumTraits<ExplicitlySizedAndSigned>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    ExplicitlySizedAndSigned emboss_reserved_local_value) {
+  return EnumTraits<ExplicitlySizedAndSigned>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(ExplicitlySizedAndSigned emboss_reserved_local_value) {
+  return EnumTraits<ExplicitlySizedAndSigned>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    ExplicitlySizedAndSigned emboss_reserved_local_value) {
+  return EnumTraits<ExplicitlySizedAndSigned>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+
+
+
+
+
+
+
+namespace ManifestEntry {
+
+
+
+namespace EmbossReservedAnonymousField1 {
+
+}  // namespace EmbossReservedAnonymousField1
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View;
+
+template <class Storage>
+class GenericEmbossReservedAnonymousField1View final {
+ public:
+  GenericEmbossReservedAnonymousField1View() : backing_() {}
+  explicit GenericEmbossReservedAnonymousField1View(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEmbossReservedAnonymousField1View(
+      const GenericEmbossReservedAnonymousField1View<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericEmbossReservedAnonymousField1View(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericEmbossReservedAnonymousField1View(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEmbossReservedAnonymousField1View<Storage> &operator=(
+      const GenericEmbossReservedAnonymousField1View<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_wide_kind_in_bits().Known()) return false;
+    if (has_wide_kind_in_bits().ValueOrDefault() && !wide_kind_in_bits().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBits().Known()) return false;
+    if (has_IntrinsicSizeInBits().ValueOrDefault() && !IntrinsicSizeInBits().Ok()) return false;
+
+
+    if (!has_MaxSizeInBits().Known()) return false;
+    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok()) return false;
+
+
+    if (!has_MinSizeInBits().Known()) return false;
+    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBits().Ok() &&
+           backing_.SizeInBits() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBits().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBits() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBits().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBits().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_wide_kind_in_bits().Known()) return false;
+    if (!emboss_reserved_local_other.has_wide_kind_in_bits().Known()) return false;
+
+    if (emboss_reserved_local_other.has_wide_kind_in_bits().ValueOrDefault() &&
+        !has_wide_kind_in_bits().ValueOrDefault())
+      return false;
+    if (has_wide_kind_in_bits().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_wide_kind_in_bits().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_wide_kind_in_bits().ValueOrDefault() &&
+        has_wide_kind_in_bits().ValueOrDefault() &&
+        !wide_kind_in_bits().Equals(emboss_reserved_local_other.wide_kind_in_bits()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_wide_kind_in_bits().ValueOr(false) &&
+        !has_wide_kind_in_bits().ValueOr(false))
+      return false;
+    if (has_wide_kind_in_bits().ValueOr(false) &&
+        !emboss_reserved_local_other.has_wide_kind_in_bits().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_wide_kind_in_bits().ValueOr(false) &&
+        has_wide_kind_in_bits().ValueOr(false) &&
+        !wide_kind_in_bits().UncheckedEquals(emboss_reserved_local_other.wide_kind_in_bits()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "wide_kind_in_bits") {
+        if (!wide_kind_in_bits().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_wide_kind_in_bits().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          wide_kind_in_bits().IsAggregate() || wide_kind_in_bits().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("wide_kind_in_bits: ");
+        wide_kind_in_bits().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !wide_kind_in_bits().IsAggregate() && !wide_kind_in_bits().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# wide_kind_in_bits: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Kind,
+    ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 4>>
+
+ wide_kind_in_bits() const;
+  ::emboss::support::Maybe<bool> has_wide_kind_in_bits() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView IntrinsicSizeInBits() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBitsView() {}
+    EmbossReservedDollarVirtualMaxSizeInBitsView(const EmbossReservedDollarVirtualMaxSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView(EmbossReservedDollarVirtualMaxSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(const EmbossReservedDollarVirtualMaxSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(EmbossReservedDollarVirtualMaxSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBitsView MaxSizeInBits() {
+    return EmbossReservedDollarVirtualMaxSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBitsView() {}
+    EmbossReservedDollarVirtualMinSizeInBitsView(const EmbossReservedDollarVirtualMinSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView(EmbossReservedDollarVirtualMinSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(const EmbossReservedDollarVirtualMinSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(EmbossReservedDollarVirtualMinSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBitsView MinSizeInBits() {
+    return EmbossReservedDollarVirtualMinSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericEmbossReservedAnonymousField1View;
+};
+using EmbossReservedAnonymousField1View =
+    GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using EmbossReservedAnonymousField1Writer =
+    GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View<
+    GenericEmbossReservedAnonymousField1View<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericEmbossReservedAnonymousField1View<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeEmbossReservedAnonymousField1View( T &&emboss_reserved_local_arg) {
+  return GenericEmbossReservedAnonymousField1View<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeEmbossReservedAnonymousField1View( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericEmbossReservedAnonymousField1View<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedEmbossReservedAnonymousField1View(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericEmbossReservedAnonymousField1View<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+}  // namespace ManifestEntry
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericManifestEntryView;
+
+template <class Storage>
+class GenericManifestEntryView final {
+ public:
+  GenericManifestEntryView() : backing_() {}
+  explicit GenericManifestEntryView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericManifestEntryView(
+      const GenericManifestEntryView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericManifestEntryView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericManifestEntryView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericManifestEntryView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericManifestEntryView<Storage> &operator=(
+      const GenericManifestEntryView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_kind().Known()) return false;
+    if (has_kind().ValueOrDefault() && !kind().Ok()) return false;
+
+
+    if (!has_count().Known()) return false;
+    if (has_count().ValueOrDefault() && !count().Ok()) return false;
+
+
+    if (!has_wide_kind().Known()) return false;
+    if (has_wide_kind().ValueOrDefault() && !wide_kind().Ok()) return false;
+
+
+    if (!has_emboss_reserved_anonymous_field_1().Known()) return false;
+    if (has_emboss_reserved_anonymous_field_1().ValueOrDefault() && !emboss_reserved_anonymous_field_1().Ok()) return false;
+
+
+    if (!has_wide_kind_in_bits().Known()) return false;
+    if (has_wide_kind_in_bits().ValueOrDefault() && !wide_kind_in_bits().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericManifestEntryView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_kind().Known()) return false;
+    if (!emboss_reserved_local_other.has_kind().Known()) return false;
+
+    if (emboss_reserved_local_other.has_kind().ValueOrDefault() &&
+        !has_kind().ValueOrDefault())
+      return false;
+    if (has_kind().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_kind().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_kind().ValueOrDefault() &&
+        has_kind().ValueOrDefault() &&
+        !kind().Equals(emboss_reserved_local_other.kind()))
+      return false;
+
+
+
+    if (!has_count().Known()) return false;
+    if (!emboss_reserved_local_other.has_count().Known()) return false;
+
+    if (emboss_reserved_local_other.has_count().ValueOrDefault() &&
+        !has_count().ValueOrDefault())
+      return false;
+    if (has_count().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_count().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_count().ValueOrDefault() &&
+        has_count().ValueOrDefault() &&
+        !count().Equals(emboss_reserved_local_other.count()))
+      return false;
+
+
+
+    if (!has_wide_kind().Known()) return false;
+    if (!emboss_reserved_local_other.has_wide_kind().Known()) return false;
+
+    if (emboss_reserved_local_other.has_wide_kind().ValueOrDefault() &&
+        !has_wide_kind().ValueOrDefault())
+      return false;
+    if (has_wide_kind().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_wide_kind().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_wide_kind().ValueOrDefault() &&
+        has_wide_kind().ValueOrDefault() &&
+        !wide_kind().Equals(emboss_reserved_local_other.wide_kind()))
+      return false;
+
+
+
+    if (!has_emboss_reserved_anonymous_field_1().Known()) return false;
+    if (!emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().Known()) return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        !has_emboss_reserved_anonymous_field_1().ValueOrDefault())
+      return false;
+    if (has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        !emboss_reserved_anonymous_field_1().Equals(emboss_reserved_local_other.emboss_reserved_anonymous_field_1()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericManifestEntryView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_kind().ValueOr(false) &&
+        !has_kind().ValueOr(false))
+      return false;
+    if (has_kind().ValueOr(false) &&
+        !emboss_reserved_local_other.has_kind().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_kind().ValueOr(false) &&
+        has_kind().ValueOr(false) &&
+        !kind().UncheckedEquals(emboss_reserved_local_other.kind()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_count().ValueOr(false) &&
+        !has_count().ValueOr(false))
+      return false;
+    if (has_count().ValueOr(false) &&
+        !emboss_reserved_local_other.has_count().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_count().ValueOr(false) &&
+        has_count().ValueOr(false) &&
+        !count().UncheckedEquals(emboss_reserved_local_other.count()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_wide_kind().ValueOr(false) &&
+        !has_wide_kind().ValueOr(false))
+      return false;
+    if (has_wide_kind().ValueOr(false) &&
+        !emboss_reserved_local_other.has_wide_kind().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_wide_kind().ValueOr(false) &&
+        has_wide_kind().ValueOr(false) &&
+        !wide_kind().UncheckedEquals(emboss_reserved_local_other.wide_kind()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        !has_emboss_reserved_anonymous_field_1().ValueOr(false))
+      return false;
+    if (has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        !emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        !emboss_reserved_anonymous_field_1().UncheckedEquals(emboss_reserved_local_other.emboss_reserved_anonymous_field_1()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericManifestEntryView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericManifestEntryView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericManifestEntryView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "kind") {
+        if (!kind().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "count") {
+        if (!count().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "wide_kind") {
+        if (!wide_kind().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "wide_kind_in_bits") {
+        if (!wide_kind_in_bits().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_kind().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          kind().IsAggregate() || kind().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("kind: ");
+        kind().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !kind().IsAggregate() && !kind().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# kind: UNREADABLE\n");
+      }
+    }
+
+    if (has_count().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          count().IsAggregate() || count().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("count: ");
+        count().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !count().IsAggregate() && !count().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# count: UNREADABLE\n");
+      }
+    }
+
+    if (has_wide_kind().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          wide_kind().IsAggregate() || wide_kind().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("wide_kind: ");
+        wide_kind().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !wide_kind().IsAggregate() && !wide_kind().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# wide_kind: UNREADABLE\n");
+      }
+    }
+
+    if (has_wide_kind_in_bits().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          wide_kind_in_bits().IsAggregate() || wide_kind_in_bits().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("wide_kind_in_bits: ");
+        wide_kind_in_bits().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !wide_kind_in_bits().IsAggregate() && !wide_kind_in_bits().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# wide_kind_in_bits: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Kind,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ kind() const;
+  ::emboss::support::Maybe<bool> has_kind() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 32>>
+
+ count() const;
+  ::emboss::support::Maybe<bool> has_count() const;
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Kind,
+    ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 5>>, 32>>
+
+ wide_kind() const;
+  ::emboss::support::Maybe<bool> has_wide_kind() const;
+
+ private:
+  typename ::emboss::test::ManifestEntry::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 9>>, 40>>
+
+ emboss_reserved_anonymous_field_1() const;
+  ::emboss::support::Maybe<bool> has_emboss_reserved_anonymous_field_1() const;
+
+ public:
+  auto wide_kind_in_bits() const -> decltype(this->emboss_reserved_anonymous_field_1().wide_kind_in_bits()) {
+   return has_wide_kind_in_bits().ValueOrDefault() ? emboss_reserved_anonymous_field_1().wide_kind_in_bits()
+                                          : decltype(this->emboss_reserved_anonymous_field_1().wide_kind_in_bits())();
+  }
+  ::emboss::support::Maybe<bool> has_wide_kind_in_bits() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericManifestEntryView;
+};
+using ManifestEntryView =
+    GenericManifestEntryView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ManifestEntryWriter =
+    GenericManifestEntryView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericManifestEntryView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericManifestEntryView<
+    GenericManifestEntryView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericManifestEntryView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeManifestEntryView( T &&emboss_reserved_local_arg) {
+  return GenericManifestEntryView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericManifestEntryView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeManifestEntryView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericManifestEntryView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericManifestEntryView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedManifestEntryView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericManifestEntryView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+namespace StructContainingEnum {
+enum class Status : ::std::uint64_t {
+  OK = static_cast</**/::std::int32_t>(0LL),
+  FAILURE = static_cast</**/::std::int32_t>(1LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<Status> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   Status *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("OK", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Status::OK;
+      return true;
+    }
+
+    if (!strcmp("FAILURE", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Status::FAILURE;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      Status emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Status::OK: return "OK";
+
+      case Status::FAILURE: return "FAILURE";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(Status emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Status::OK: return true;
+
+      case Status::FAILURE: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       Status emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<Status>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    Status *emboss_reserved_local_result) {
+  return EnumTraits<Status>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    Status emboss_reserved_local_value) {
+  return EnumTraits<Status>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(Status emboss_reserved_local_value) {
+  return EnumTraits<Status>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    Status emboss_reserved_local_value) {
+  return EnumTraits<Status>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+
+}  // namespace StructContainingEnum
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructContainingEnumView;
+
+template <class Storage>
+class GenericStructContainingEnumView final {
+ public:
+  GenericStructContainingEnumView() : backing_() {}
+  explicit GenericStructContainingEnumView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructContainingEnumView(
+      const GenericStructContainingEnumView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericStructContainingEnumView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericStructContainingEnumView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericStructContainingEnumView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructContainingEnumView<Storage> &operator=(
+      const GenericStructContainingEnumView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+    using Status = ::emboss::test::StructContainingEnum::Status;
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_bar().Known()) return false;
+    if (has_bar().ValueOrDefault() && !bar().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericStructContainingEnumView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_bar().Known()) return false;
+    if (!emboss_reserved_local_other.has_bar().Known()) return false;
+
+    if (emboss_reserved_local_other.has_bar().ValueOrDefault() &&
+        !has_bar().ValueOrDefault())
+      return false;
+    if (has_bar().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_bar().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_bar().ValueOrDefault() &&
+        has_bar().ValueOrDefault() &&
+        !bar().Equals(emboss_reserved_local_other.bar()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericStructContainingEnumView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_bar().ValueOr(false) &&
+        !has_bar().ValueOr(false))
+      return false;
+    if (has_bar().ValueOr(false) &&
+        !emboss_reserved_local_other.has_bar().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_bar().ValueOr(false) &&
+        has_bar().ValueOr(false) &&
+        !bar().UncheckedEquals(emboss_reserved_local_other.bar()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericStructContainingEnumView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericStructContainingEnumView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericStructContainingEnumView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "bar") {
+        if (!bar().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_bar().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          bar().IsAggregate() || bar().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("bar: ");
+        bar().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !bar().IsAggregate() && !bar().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# bar: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ bar() const;
+  ::emboss::support::Maybe<bool> has_bar() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericStructContainingEnumView;
+};
+using StructContainingEnumView =
+    GenericStructContainingEnumView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using StructContainingEnumWriter =
+    GenericStructContainingEnumView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructContainingEnumView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericStructContainingEnumView<
+    GenericStructContainingEnumView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericStructContainingEnumView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeStructContainingEnumView( T &&emboss_reserved_local_arg) {
+  return GenericStructContainingEnumView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericStructContainingEnumView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeStructContainingEnumView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericStructContainingEnumView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericStructContainingEnumView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedStructContainingEnumView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericStructContainingEnumView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace Constants {
+
+}  // namespace Constants
+
+
+namespace Constants {
+inline constexpr ::std::int32_t sprocket() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace Constants
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConstantsView<Storage>::EmbossReservedVirtualSprocketView::Read() {
+  return Constants::sprocket();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConstantsView<
+    Storage>::EmbossReservedVirtualSprocketView::UncheckedRead() {
+  return Constants::sprocket();
+}
+
+namespace Constants {
+inline constexpr ::std::int32_t geegaw() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace Constants
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConstantsView<Storage>::EmbossReservedVirtualGeegawView::Read() {
+  return Constants::geegaw();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConstantsView<
+    Storage>::EmbossReservedVirtualGeegawView::UncheckedRead() {
+  return Constants::geegaw();
+}
+
+namespace Constants {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)).ValueOrDefault();
+}
+}  // namespace Constants
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConstantsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Constants::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConstantsView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Constants::IntrinsicSizeInBytes();
+}
+
+namespace Constants {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)).ValueOrDefault();
+}
+}  // namespace Constants
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConstantsView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Constants::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConstantsView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Constants::MaxSizeInBytes();
+}
+
+namespace Constants {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)).ValueOrDefault();
+}
+}  // namespace Constants
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConstantsView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Constants::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConstantsView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Constants::MinSizeInBytes();
+}
+namespace ManifestEntry {
+namespace EmbossReservedAnonymousField1 {
+
+}  // namespace EmbossReservedAnonymousField1
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Kind,
+    ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 4>>
+
+ GenericEmbossReservedAnonymousField1View<Storage>::wide_kind_in_bits()
+    const {
+
+  if ( has_wide_kind_in_bits().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(32LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Kind,
+    ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 4>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   4>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Kind,
+    ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 4>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField1View<Storage>::has_wide_kind_in_bits() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace EmbossReservedAnonymousField1 {
+inline constexpr ::std::int32_t IntrinsicSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(36LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField1
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField1::IntrinsicSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField1::IntrinsicSizeInBits();
+}
+
+namespace EmbossReservedAnonymousField1 {
+inline constexpr ::std::int32_t MaxSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(36LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField1
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField1::MaxSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField1::MaxSizeInBits();
+}
+
+namespace EmbossReservedAnonymousField1 {
+inline constexpr ::std::int32_t MinSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(36LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField1
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField1::MinSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField1::MinSizeInBits();
+}
+
+}  // namespace ManifestEntry
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Kind,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericManifestEntryView<Storage>::kind()
+    const {
+
+  if ( has_kind().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Kind,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Kind,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericManifestEntryView<Storage>::has_kind() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 32>>
+
+ GenericManifestEntryView<Storage>::count()
+    const {
+
+  if ( has_count().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericManifestEntryView<Storage>::has_count() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Kind,
+    ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 5>>, 32>>
+
+ GenericManifestEntryView<Storage>::wide_kind()
+    const {
+
+  if ( has_wide_kind().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Kind,
+    ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 5>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   5>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Kind,
+    ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 5>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericManifestEntryView<Storage>::has_wide_kind() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::ManifestEntry::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 9>>, 40>>
+
+ GenericManifestEntryView<Storage>::emboss_reserved_anonymous_field_1()
+    const {
+
+  if ( has_emboss_reserved_anonymous_field_1().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(9LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::ManifestEntry::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 9>>, 40>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   9>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::ManifestEntry::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 9>>, 40>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericManifestEntryView<Storage>::has_emboss_reserved_anonymous_field_1() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericManifestEntryView<Storage>::has_wide_kind_in_bits() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+namespace ManifestEntry {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(14LL)).ValueOrDefault();
+}
+}  // namespace ManifestEntry
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericManifestEntryView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return ManifestEntry::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericManifestEntryView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return ManifestEntry::IntrinsicSizeInBytes();
+}
+
+namespace ManifestEntry {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(14LL)).ValueOrDefault();
+}
+}  // namespace ManifestEntry
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericManifestEntryView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return ManifestEntry::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericManifestEntryView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return ManifestEntry::MaxSizeInBytes();
+}
+
+namespace ManifestEntry {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(14LL)).ValueOrDefault();
+}
+}  // namespace ManifestEntry
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericManifestEntryView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return ManifestEntry::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericManifestEntryView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return ManifestEntry::MinSizeInBytes();
+}
+namespace StructContainingEnum {
+
+}  // namespace StructContainingEnum
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericStructContainingEnumView<Storage>::bar()
+    const {
+
+  if ( has_bar().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructContainingEnumView<Storage>::has_bar() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace StructContainingEnum {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace StructContainingEnum
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructContainingEnumView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return StructContainingEnum::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructContainingEnumView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return StructContainingEnum::IntrinsicSizeInBytes();
+}
+
+namespace StructContainingEnum {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace StructContainingEnum
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructContainingEnumView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return StructContainingEnum::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructContainingEnumView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return StructContainingEnum::MaxSizeInBytes();
+}
+
+namespace StructContainingEnum {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace StructContainingEnum
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructContainingEnumView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return StructContainingEnum::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructContainingEnumView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return StructContainingEnum::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_ENUM_EMB_H_
+
diff --git a/testdata/golden_cpp/enum_case.emb.h b/testdata/golden_cpp/enum_case.emb.h
new file mode 100644
index 0000000..5738596
--- /dev/null
+++ b/testdata/golden_cpp/enum_case.emb.h
@@ -0,0 +1,1274 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_ENUM_CASE_EMB_H_
+#define TESTDATA_ENUM_CASE_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+enum class EnumShouty : ::std::uint64_t;
+
+enum class EnumDefault : ::std::uint64_t;
+
+namespace UseKCamelEnumCase {
+
+}  // namespace UseKCamelEnumCase
+
+
+template <class Storage>
+class GenericUseKCamelEnumCaseView;
+
+enum class EnumShoutyAndKCamel : ::std::uint64_t;
+
+enum class EnumMixed : ::std::uint64_t;
+
+
+enum class EnumShouty : ::std::uint64_t {
+  FIRST = static_cast</**/::std::int32_t>(0LL),
+  SECOND = static_cast</**/::std::int32_t>(1LL),
+  TWO_WORD = static_cast</**/::std::int32_t>(2LL),
+  THREE_WORD_ENUM = static_cast</**/::std::int32_t>(4LL),
+  LONG_ENUM_VALUE_NAME = static_cast</**/::std::int32_t>(8LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<EnumShouty> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   EnumShouty *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("FIRST", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumShouty::FIRST;
+      return true;
+    }
+
+    if (!strcmp("SECOND", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumShouty::SECOND;
+      return true;
+    }
+
+    if (!strcmp("TWO_WORD", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumShouty::TWO_WORD;
+      return true;
+    }
+
+    if (!strcmp("THREE_WORD_ENUM", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumShouty::THREE_WORD_ENUM;
+      return true;
+    }
+
+    if (!strcmp("LONG_ENUM_VALUE_NAME", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumShouty::LONG_ENUM_VALUE_NAME;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      EnumShouty emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case EnumShouty::FIRST: return "FIRST";
+
+      case EnumShouty::SECOND: return "SECOND";
+
+      case EnumShouty::TWO_WORD: return "TWO_WORD";
+
+      case EnumShouty::THREE_WORD_ENUM: return "THREE_WORD_ENUM";
+
+      case EnumShouty::LONG_ENUM_VALUE_NAME: return "LONG_ENUM_VALUE_NAME";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(EnumShouty emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case EnumShouty::FIRST: return true;
+
+      case EnumShouty::SECOND: return true;
+
+      case EnumShouty::TWO_WORD: return true;
+
+      case EnumShouty::THREE_WORD_ENUM: return true;
+
+      case EnumShouty::LONG_ENUM_VALUE_NAME: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       EnumShouty emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<EnumShouty>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    EnumShouty *emboss_reserved_local_result) {
+  return EnumTraits<EnumShouty>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    EnumShouty emboss_reserved_local_value) {
+  return EnumTraits<EnumShouty>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(EnumShouty emboss_reserved_local_value) {
+  return EnumTraits<EnumShouty>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    EnumShouty emboss_reserved_local_value) {
+  return EnumTraits<EnumShouty>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+enum class EnumDefault : ::std::uint64_t {
+  kFirst = static_cast</**/::std::int32_t>(0LL),
+  kSecond = static_cast</**/::std::int32_t>(1LL),
+  kTwoWord = static_cast</**/::std::int32_t>(2LL),
+  kThreeWordEnum = static_cast</**/::std::int32_t>(4LL),
+  kLongEnumValueName = static_cast</**/::std::int32_t>(8LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<EnumDefault> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   EnumDefault *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("FIRST", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumDefault::kFirst;
+      return true;
+    }
+
+    if (!strcmp("SECOND", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumDefault::kSecond;
+      return true;
+    }
+
+    if (!strcmp("TWO_WORD", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumDefault::kTwoWord;
+      return true;
+    }
+
+    if (!strcmp("THREE_WORD_ENUM", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumDefault::kThreeWordEnum;
+      return true;
+    }
+
+    if (!strcmp("LONG_ENUM_VALUE_NAME", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumDefault::kLongEnumValueName;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      EnumDefault emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case EnumDefault::kFirst: return "FIRST";
+
+      case EnumDefault::kSecond: return "SECOND";
+
+      case EnumDefault::kTwoWord: return "TWO_WORD";
+
+      case EnumDefault::kThreeWordEnum: return "THREE_WORD_ENUM";
+
+      case EnumDefault::kLongEnumValueName: return "LONG_ENUM_VALUE_NAME";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(EnumDefault emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case EnumDefault::kFirst: return true;
+
+      case EnumDefault::kSecond: return true;
+
+      case EnumDefault::kTwoWord: return true;
+
+      case EnumDefault::kThreeWordEnum: return true;
+
+      case EnumDefault::kLongEnumValueName: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       EnumDefault emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<EnumDefault>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    EnumDefault *emboss_reserved_local_result) {
+  return EnumTraits<EnumDefault>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    EnumDefault emboss_reserved_local_value) {
+  return EnumTraits<EnumDefault>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(EnumDefault emboss_reserved_local_value) {
+  return EnumTraits<EnumDefault>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    EnumDefault emboss_reserved_local_value) {
+  return EnumTraits<EnumDefault>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+
+
+
+
+
+namespace UseKCamelEnumCase {
+
+}  // namespace UseKCamelEnumCase
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericUseKCamelEnumCaseView;
+
+template <class Storage>
+class GenericUseKCamelEnumCaseView final {
+ public:
+  GenericUseKCamelEnumCaseView() : backing_() {}
+  explicit GenericUseKCamelEnumCaseView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericUseKCamelEnumCaseView(
+      const GenericUseKCamelEnumCaseView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericUseKCamelEnumCaseView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericUseKCamelEnumCaseView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericUseKCamelEnumCaseView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericUseKCamelEnumCaseView<Storage> &operator=(
+      const GenericUseKCamelEnumCaseView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_v().Known()) return false;
+    if (has_v().ValueOrDefault() && !v().Ok()) return false;
+
+
+    if (!has_first().Known()) return false;
+    if (has_first().ValueOrDefault() && !first().Ok()) return false;
+
+
+    if (!has_v_is_first().Known()) return false;
+    if (has_v_is_first().ValueOrDefault() && !v_is_first().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericUseKCamelEnumCaseView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_v().Known()) return false;
+    if (!emboss_reserved_local_other.has_v().Known()) return false;
+
+    if (emboss_reserved_local_other.has_v().ValueOrDefault() &&
+        !has_v().ValueOrDefault())
+      return false;
+    if (has_v().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_v().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_v().ValueOrDefault() &&
+        has_v().ValueOrDefault() &&
+        !v().Equals(emboss_reserved_local_other.v()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericUseKCamelEnumCaseView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_v().ValueOr(false) &&
+        !has_v().ValueOr(false))
+      return false;
+    if (has_v().ValueOr(false) &&
+        !emboss_reserved_local_other.has_v().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_v().ValueOr(false) &&
+        has_v().ValueOr(false) &&
+        !v().UncheckedEquals(emboss_reserved_local_other.v()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericUseKCamelEnumCaseView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericUseKCamelEnumCaseView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericUseKCamelEnumCaseView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "v") {
+        if (!v().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_v().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          v().IsAggregate() || v().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("v: ");
+        v().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !v().IsAggregate() && !v().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# v: UNREADABLE\n");
+      }
+    }
+
+    if (has_first().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          first().IsAggregate() || first().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# first: ");
+        first().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# first: UNREADABLE\n");
+      }
+    }
+
+    if (has_v_is_first().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          v_is_first().IsAggregate() || v_is_first().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# v_is_first: ");
+        v_is_first().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# v_is_first: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::EnumDefault,
+    ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ v() const;
+  ::emboss::support::Maybe<bool> has_v() const;
+
+ public:
+  class EmbossReservedVirtualFirstView final {
+   public:
+    using ValueType = ::emboss::test::EnumDefault;
+
+    constexpr EmbossReservedVirtualFirstView() {}
+    EmbossReservedVirtualFirstView(const EmbossReservedVirtualFirstView &) = default;
+    EmbossReservedVirtualFirstView(EmbossReservedVirtualFirstView &&) = default;
+    EmbossReservedVirtualFirstView &operator=(const EmbossReservedVirtualFirstView &) =
+        default;
+    EmbossReservedVirtualFirstView &operator=(EmbossReservedVirtualFirstView &&) =
+        default;
+    ~EmbossReservedVirtualFirstView() = default;
+
+    static constexpr ::emboss::test::EnumDefault Read();
+    static constexpr ::emboss::test::EnumDefault UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteEnumViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedVirtualFirstView first() {
+    return EmbossReservedVirtualFirstView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_first() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedVirtualVIsFirstView final {
+   public:
+    using ValueType = bool;
+
+    explicit EmbossReservedVirtualVIsFirstView(
+        const GenericUseKCamelEnumCaseView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualVIsFirstView() = delete;
+    EmbossReservedVirtualVIsFirstView(const EmbossReservedVirtualVIsFirstView &) = default;
+    EmbossReservedVirtualVIsFirstView(EmbossReservedVirtualVIsFirstView &&) = default;
+    EmbossReservedVirtualVIsFirstView &operator=(const EmbossReservedVirtualVIsFirstView &) =
+        default;
+    EmbossReservedVirtualVIsFirstView &operator=(EmbossReservedVirtualVIsFirstView &&) =
+        default;
+    ~EmbossReservedVirtualVIsFirstView() = default;
+
+    bool Read() const {
+      EMBOSS_CHECK(view_.has_v_is_first().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    bool UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteBooleanViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ bool> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.v();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::emboss::test::EnumDefault>(static_cast</**/::emboss::test::EnumDefault>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::EnumDefault>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Equal</**/::emboss::test::EnumDefault, bool, ::emboss::test::EnumDefault, ::emboss::test::EnumDefault>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::emboss::test::EnumDefault>(static_cast</**/::emboss::test::EnumDefault>(0)));
+
+      return emboss_reserved_local_subexpr_3;
+    }
+
+    static constexpr bool ValueIsOk(
+        bool emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericUseKCamelEnumCaseView view_;
+  };
+  EmbossReservedVirtualVIsFirstView v_is_first() const;
+  ::emboss::support::Maybe<bool> has_v_is_first() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericUseKCamelEnumCaseView;
+};
+using UseKCamelEnumCaseView =
+    GenericUseKCamelEnumCaseView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using UseKCamelEnumCaseWriter =
+    GenericUseKCamelEnumCaseView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericUseKCamelEnumCaseView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericUseKCamelEnumCaseView<
+    GenericUseKCamelEnumCaseView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericUseKCamelEnumCaseView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeUseKCamelEnumCaseView( T &&emboss_reserved_local_arg) {
+  return GenericUseKCamelEnumCaseView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericUseKCamelEnumCaseView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeUseKCamelEnumCaseView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericUseKCamelEnumCaseView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericUseKCamelEnumCaseView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedUseKCamelEnumCaseView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericUseKCamelEnumCaseView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+enum class EnumShoutyAndKCamel : ::std::uint64_t {
+  FIRST = static_cast</**/::std::int32_t>(0LL),
+  kFirst = static_cast</**/::std::int32_t>(0LL),
+  SECOND = static_cast</**/::std::int32_t>(1LL),
+  kSecond = static_cast</**/::std::int32_t>(1LL),
+  TWO_WORD = static_cast</**/::std::int32_t>(2LL),
+  kTwoWord = static_cast</**/::std::int32_t>(2LL),
+  THREE_WORD_ENUM = static_cast</**/::std::int32_t>(4LL),
+  kThreeWordEnum = static_cast</**/::std::int32_t>(4LL),
+  LONG_ENUM_VALUE_NAME = static_cast</**/::std::int32_t>(8LL),
+  kLongEnumValueName = static_cast</**/::std::int32_t>(8LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<EnumShoutyAndKCamel> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   EnumShoutyAndKCamel *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("FIRST", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumShoutyAndKCamel::FIRST;
+      return true;
+    }
+
+    if (!strcmp("FIRST", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumShoutyAndKCamel::kFirst;
+      return true;
+    }
+
+    if (!strcmp("SECOND", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumShoutyAndKCamel::SECOND;
+      return true;
+    }
+
+    if (!strcmp("SECOND", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumShoutyAndKCamel::kSecond;
+      return true;
+    }
+
+    if (!strcmp("TWO_WORD", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumShoutyAndKCamel::TWO_WORD;
+      return true;
+    }
+
+    if (!strcmp("TWO_WORD", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumShoutyAndKCamel::kTwoWord;
+      return true;
+    }
+
+    if (!strcmp("THREE_WORD_ENUM", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumShoutyAndKCamel::THREE_WORD_ENUM;
+      return true;
+    }
+
+    if (!strcmp("THREE_WORD_ENUM", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumShoutyAndKCamel::kThreeWordEnum;
+      return true;
+    }
+
+    if (!strcmp("LONG_ENUM_VALUE_NAME", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumShoutyAndKCamel::LONG_ENUM_VALUE_NAME;
+      return true;
+    }
+
+    if (!strcmp("LONG_ENUM_VALUE_NAME", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumShoutyAndKCamel::kLongEnumValueName;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      EnumShoutyAndKCamel emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case EnumShoutyAndKCamel::FIRST: return "FIRST";
+
+      case EnumShoutyAndKCamel::SECOND: return "SECOND";
+
+      case EnumShoutyAndKCamel::TWO_WORD: return "TWO_WORD";
+
+      case EnumShoutyAndKCamel::THREE_WORD_ENUM: return "THREE_WORD_ENUM";
+
+      case EnumShoutyAndKCamel::LONG_ENUM_VALUE_NAME: return "LONG_ENUM_VALUE_NAME";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(EnumShoutyAndKCamel emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case EnumShoutyAndKCamel::FIRST: return true;
+
+      case EnumShoutyAndKCamel::SECOND: return true;
+
+      case EnumShoutyAndKCamel::TWO_WORD: return true;
+
+      case EnumShoutyAndKCamel::THREE_WORD_ENUM: return true;
+
+      case EnumShoutyAndKCamel::LONG_ENUM_VALUE_NAME: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       EnumShoutyAndKCamel emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<EnumShoutyAndKCamel>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    EnumShoutyAndKCamel *emboss_reserved_local_result) {
+  return EnumTraits<EnumShoutyAndKCamel>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    EnumShoutyAndKCamel emboss_reserved_local_value) {
+  return EnumTraits<EnumShoutyAndKCamel>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(EnumShoutyAndKCamel emboss_reserved_local_value) {
+  return EnumTraits<EnumShoutyAndKCamel>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    EnumShoutyAndKCamel emboss_reserved_local_value) {
+  return EnumTraits<EnumShoutyAndKCamel>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+enum class EnumMixed : ::std::uint64_t {
+  FIRST = static_cast</**/::std::int32_t>(0LL),
+  kFirst = static_cast</**/::std::int32_t>(0LL),
+  SECOND = static_cast</**/::std::int32_t>(1LL),
+  kTwoWord = static_cast</**/::std::int32_t>(2LL),
+  kThreeWordEnum = static_cast</**/::std::int32_t>(4LL),
+  THREE_WORD_ENUM = static_cast</**/::std::int32_t>(4LL),
+  kLongEnumValueName = static_cast</**/::std::int32_t>(8LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<EnumMixed> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   EnumMixed *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("FIRST", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumMixed::FIRST;
+      return true;
+    }
+
+    if (!strcmp("FIRST", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumMixed::kFirst;
+      return true;
+    }
+
+    if (!strcmp("SECOND", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumMixed::SECOND;
+      return true;
+    }
+
+    if (!strcmp("TWO_WORD", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumMixed::kTwoWord;
+      return true;
+    }
+
+    if (!strcmp("THREE_WORD_ENUM", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumMixed::kThreeWordEnum;
+      return true;
+    }
+
+    if (!strcmp("THREE_WORD_ENUM", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumMixed::THREE_WORD_ENUM;
+      return true;
+    }
+
+    if (!strcmp("LONG_ENUM_VALUE_NAME", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = EnumMixed::kLongEnumValueName;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      EnumMixed emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case EnumMixed::FIRST: return "FIRST";
+
+      case EnumMixed::SECOND: return "SECOND";
+
+      case EnumMixed::kTwoWord: return "TWO_WORD";
+
+      case EnumMixed::kThreeWordEnum: return "THREE_WORD_ENUM";
+
+      case EnumMixed::kLongEnumValueName: return "LONG_ENUM_VALUE_NAME";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(EnumMixed emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case EnumMixed::FIRST: return true;
+
+      case EnumMixed::SECOND: return true;
+
+      case EnumMixed::kTwoWord: return true;
+
+      case EnumMixed::kThreeWordEnum: return true;
+
+      case EnumMixed::kLongEnumValueName: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       EnumMixed emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<EnumMixed>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    EnumMixed *emboss_reserved_local_result) {
+  return EnumTraits<EnumMixed>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    EnumMixed emboss_reserved_local_value) {
+  return EnumTraits<EnumMixed>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(EnumMixed emboss_reserved_local_value) {
+  return EnumTraits<EnumMixed>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    EnumMixed emboss_reserved_local_value) {
+  return EnumTraits<EnumMixed>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+
+namespace UseKCamelEnumCase {
+
+}  // namespace UseKCamelEnumCase
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::EnumDefault,
+    ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ GenericUseKCamelEnumCaseView<Storage>::v()
+    const {
+
+  if ( has_v().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::EnumDefault,
+    ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::EnumDefault,
+    ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericUseKCamelEnumCaseView<Storage>::has_v() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace UseKCamelEnumCase {
+inline constexpr ::emboss::test::EnumDefault first() {
+  return ::emboss::support::Maybe</**/::emboss::test::EnumDefault>(static_cast</**/::emboss::test::EnumDefault>(0)).ValueOrDefault();
+}
+}  // namespace UseKCamelEnumCase
+
+template <class Storage>
+inline constexpr ::emboss::test::EnumDefault
+GenericUseKCamelEnumCaseView<Storage>::EmbossReservedVirtualFirstView::Read() {
+  return UseKCamelEnumCase::first();
+}
+
+template <class Storage>
+inline constexpr ::emboss::test::EnumDefault
+GenericUseKCamelEnumCaseView<
+    Storage>::EmbossReservedVirtualFirstView::UncheckedRead() {
+  return UseKCamelEnumCase::first();
+}
+
+template <class Storage>
+inline typename GenericUseKCamelEnumCaseView<Storage>::EmbossReservedVirtualVIsFirstView
+GenericUseKCamelEnumCaseView<Storage>::v_is_first() const {
+  return
+      typename GenericUseKCamelEnumCaseView<Storage>::EmbossReservedVirtualVIsFirstView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericUseKCamelEnumCaseView<Storage>::has_v_is_first() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace UseKCamelEnumCase {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace UseKCamelEnumCase
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericUseKCamelEnumCaseView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return UseKCamelEnumCase::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericUseKCamelEnumCaseView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return UseKCamelEnumCase::IntrinsicSizeInBytes();
+}
+
+namespace UseKCamelEnumCase {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace UseKCamelEnumCase
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericUseKCamelEnumCaseView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return UseKCamelEnumCase::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericUseKCamelEnumCaseView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return UseKCamelEnumCase::MaxSizeInBytes();
+}
+
+namespace UseKCamelEnumCase {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace UseKCamelEnumCase
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericUseKCamelEnumCaseView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return UseKCamelEnumCase::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericUseKCamelEnumCaseView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return UseKCamelEnumCase::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_ENUM_CASE_EMB_H_
+
diff --git a/testdata/golden_cpp/explicit_sizes.emb.h b/testdata/golden_cpp/explicit_sizes.emb.h
new file mode 100644
index 0000000..f8fd46f
--- /dev/null
+++ b/testdata/golden_cpp/explicit_sizes.emb.h
@@ -0,0 +1,3199 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_EXPLICIT_SIZES_EMB_H_
+#define TESTDATA_EXPLICIT_SIZES_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace SizedUIntArrays {
+
+}  // namespace SizedUIntArrays
+
+
+template <class Storage>
+class GenericSizedUIntArraysView;
+
+namespace SizedIntArrays {
+
+}  // namespace SizedIntArrays
+
+
+template <class Storage>
+class GenericSizedIntArraysView;
+
+namespace SizedEnumArrays {
+
+}  // namespace SizedEnumArrays
+
+
+template <class Storage>
+class GenericSizedEnumArraysView;
+
+namespace BitArrayContainer {
+
+}  // namespace BitArrayContainer
+
+
+template <class Storage>
+class GenericBitArrayContainerView;
+
+enum class Enum : ::std::uint64_t;
+
+
+
+
+
+
+
+namespace SizedUIntArrays {
+
+}  // namespace SizedUIntArrays
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericSizedUIntArraysView;
+
+template <class Storage>
+class GenericSizedUIntArraysView final {
+ public:
+  GenericSizedUIntArraysView() : backing_() {}
+  explicit GenericSizedUIntArraysView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericSizedUIntArraysView(
+      const GenericSizedUIntArraysView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericSizedUIntArraysView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericSizedUIntArraysView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericSizedUIntArraysView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericSizedUIntArraysView<Storage> &operator=(
+      const GenericSizedUIntArraysView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_one_nibble().Known()) return false;
+    if (has_one_nibble().ValueOrDefault() && !one_nibble().Ok()) return false;
+
+
+    if (!has_two_nibble().Known()) return false;
+    if (has_two_nibble().ValueOrDefault() && !two_nibble().Ok()) return false;
+
+
+    if (!has_four_nibble().Known()) return false;
+    if (has_four_nibble().ValueOrDefault() && !four_nibble().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBits().Known()) return false;
+    if (has_IntrinsicSizeInBits().ValueOrDefault() && !IntrinsicSizeInBits().Ok()) return false;
+
+
+    if (!has_MaxSizeInBits().Known()) return false;
+    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok()) return false;
+
+
+    if (!has_MinSizeInBits().Known()) return false;
+    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBits().Ok() &&
+           backing_.SizeInBits() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBits().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBits() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBits().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBits().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericSizedUIntArraysView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_one_nibble().Known()) return false;
+    if (!emboss_reserved_local_other.has_one_nibble().Known()) return false;
+
+    if (emboss_reserved_local_other.has_one_nibble().ValueOrDefault() &&
+        !has_one_nibble().ValueOrDefault())
+      return false;
+    if (has_one_nibble().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_one_nibble().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_one_nibble().ValueOrDefault() &&
+        has_one_nibble().ValueOrDefault() &&
+        !one_nibble().Equals(emboss_reserved_local_other.one_nibble()))
+      return false;
+
+
+
+    if (!has_two_nibble().Known()) return false;
+    if (!emboss_reserved_local_other.has_two_nibble().Known()) return false;
+
+    if (emboss_reserved_local_other.has_two_nibble().ValueOrDefault() &&
+        !has_two_nibble().ValueOrDefault())
+      return false;
+    if (has_two_nibble().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_two_nibble().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_two_nibble().ValueOrDefault() &&
+        has_two_nibble().ValueOrDefault() &&
+        !two_nibble().Equals(emboss_reserved_local_other.two_nibble()))
+      return false;
+
+
+
+    if (!has_four_nibble().Known()) return false;
+    if (!emboss_reserved_local_other.has_four_nibble().Known()) return false;
+
+    if (emboss_reserved_local_other.has_four_nibble().ValueOrDefault() &&
+        !has_four_nibble().ValueOrDefault())
+      return false;
+    if (has_four_nibble().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_four_nibble().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_four_nibble().ValueOrDefault() &&
+        has_four_nibble().ValueOrDefault() &&
+        !four_nibble().Equals(emboss_reserved_local_other.four_nibble()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericSizedUIntArraysView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_one_nibble().ValueOr(false) &&
+        !has_one_nibble().ValueOr(false))
+      return false;
+    if (has_one_nibble().ValueOr(false) &&
+        !emboss_reserved_local_other.has_one_nibble().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_one_nibble().ValueOr(false) &&
+        has_one_nibble().ValueOr(false) &&
+        !one_nibble().UncheckedEquals(emboss_reserved_local_other.one_nibble()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_two_nibble().ValueOr(false) &&
+        !has_two_nibble().ValueOr(false))
+      return false;
+    if (has_two_nibble().ValueOr(false) &&
+        !emboss_reserved_local_other.has_two_nibble().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_two_nibble().ValueOr(false) &&
+        has_two_nibble().ValueOr(false) &&
+        !two_nibble().UncheckedEquals(emboss_reserved_local_other.two_nibble()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_four_nibble().ValueOr(false) &&
+        !has_four_nibble().ValueOr(false))
+      return false;
+    if (has_four_nibble().ValueOr(false) &&
+        !emboss_reserved_local_other.has_four_nibble().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_four_nibble().ValueOr(false) &&
+        has_four_nibble().ValueOr(false) &&
+        !four_nibble().UncheckedEquals(emboss_reserved_local_other.four_nibble()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericSizedUIntArraysView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericSizedUIntArraysView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericSizedUIntArraysView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "one_nibble") {
+        if (!one_nibble().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "two_nibble") {
+        if (!two_nibble().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "four_nibble") {
+        if (!four_nibble().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_one_nibble().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          one_nibble().IsAggregate() || one_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("one_nibble: ");
+        one_nibble().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !one_nibble().IsAggregate() && !one_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# one_nibble: UNREADABLE\n");
+      }
+    }
+
+    if (has_two_nibble().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          two_nibble().IsAggregate() || two_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("two_nibble: ");
+        two_nibble().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !two_nibble().IsAggregate() && !two_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# two_nibble: UNREADABLE\n");
+      }
+    }
+
+    if (has_four_nibble().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          four_nibble().IsAggregate() || four_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("four_nibble: ");
+        four_nibble().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !four_nibble().IsAggregate() && !four_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# four_nibble: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/4, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 4,
+    1 >
+
+ one_nibble() const;
+  ::emboss::support::Maybe<bool> has_one_nibble() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 8>::template OffsetStorageType</**/8, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 8>, 8,
+    1 >
+
+ two_nibble() const;
+  ::emboss::support::Maybe<bool> has_two_nibble() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 24>::template OffsetStorageType</**/16, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 24>, 16,
+    1 >
+
+ four_nibble() const;
+  ::emboss::support::Maybe<bool> has_four_nibble() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView IntrinsicSizeInBits() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBitsView() {}
+    EmbossReservedDollarVirtualMaxSizeInBitsView(const EmbossReservedDollarVirtualMaxSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView(EmbossReservedDollarVirtualMaxSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(const EmbossReservedDollarVirtualMaxSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(EmbossReservedDollarVirtualMaxSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBitsView MaxSizeInBits() {
+    return EmbossReservedDollarVirtualMaxSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBitsView() {}
+    EmbossReservedDollarVirtualMinSizeInBitsView(const EmbossReservedDollarVirtualMinSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView(EmbossReservedDollarVirtualMinSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(const EmbossReservedDollarVirtualMinSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(EmbossReservedDollarVirtualMinSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBitsView MinSizeInBits() {
+    return EmbossReservedDollarVirtualMinSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericSizedUIntArraysView;
+};
+using SizedUIntArraysView =
+    GenericSizedUIntArraysView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using SizedUIntArraysWriter =
+    GenericSizedUIntArraysView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericSizedUIntArraysView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericSizedUIntArraysView<
+    GenericSizedUIntArraysView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericSizedUIntArraysView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeSizedUIntArraysView( T &&emboss_reserved_local_arg) {
+  return GenericSizedUIntArraysView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericSizedUIntArraysView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeSizedUIntArraysView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericSizedUIntArraysView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericSizedUIntArraysView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedSizedUIntArraysView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericSizedUIntArraysView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace SizedIntArrays {
+
+}  // namespace SizedIntArrays
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericSizedIntArraysView;
+
+template <class Storage>
+class GenericSizedIntArraysView final {
+ public:
+  GenericSizedIntArraysView() : backing_() {}
+  explicit GenericSizedIntArraysView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericSizedIntArraysView(
+      const GenericSizedIntArraysView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericSizedIntArraysView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericSizedIntArraysView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericSizedIntArraysView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericSizedIntArraysView<Storage> &operator=(
+      const GenericSizedIntArraysView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_one_nibble().Known()) return false;
+    if (has_one_nibble().ValueOrDefault() && !one_nibble().Ok()) return false;
+
+
+    if (!has_two_nibble().Known()) return false;
+    if (has_two_nibble().ValueOrDefault() && !two_nibble().Ok()) return false;
+
+
+    if (!has_four_nibble().Known()) return false;
+    if (has_four_nibble().ValueOrDefault() && !four_nibble().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBits().Known()) return false;
+    if (has_IntrinsicSizeInBits().ValueOrDefault() && !IntrinsicSizeInBits().Ok()) return false;
+
+
+    if (!has_MaxSizeInBits().Known()) return false;
+    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok()) return false;
+
+
+    if (!has_MinSizeInBits().Known()) return false;
+    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBits().Ok() &&
+           backing_.SizeInBits() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBits().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBits() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBits().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBits().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericSizedIntArraysView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_one_nibble().Known()) return false;
+    if (!emboss_reserved_local_other.has_one_nibble().Known()) return false;
+
+    if (emboss_reserved_local_other.has_one_nibble().ValueOrDefault() &&
+        !has_one_nibble().ValueOrDefault())
+      return false;
+    if (has_one_nibble().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_one_nibble().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_one_nibble().ValueOrDefault() &&
+        has_one_nibble().ValueOrDefault() &&
+        !one_nibble().Equals(emboss_reserved_local_other.one_nibble()))
+      return false;
+
+
+
+    if (!has_two_nibble().Known()) return false;
+    if (!emboss_reserved_local_other.has_two_nibble().Known()) return false;
+
+    if (emboss_reserved_local_other.has_two_nibble().ValueOrDefault() &&
+        !has_two_nibble().ValueOrDefault())
+      return false;
+    if (has_two_nibble().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_two_nibble().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_two_nibble().ValueOrDefault() &&
+        has_two_nibble().ValueOrDefault() &&
+        !two_nibble().Equals(emboss_reserved_local_other.two_nibble()))
+      return false;
+
+
+
+    if (!has_four_nibble().Known()) return false;
+    if (!emboss_reserved_local_other.has_four_nibble().Known()) return false;
+
+    if (emboss_reserved_local_other.has_four_nibble().ValueOrDefault() &&
+        !has_four_nibble().ValueOrDefault())
+      return false;
+    if (has_four_nibble().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_four_nibble().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_four_nibble().ValueOrDefault() &&
+        has_four_nibble().ValueOrDefault() &&
+        !four_nibble().Equals(emboss_reserved_local_other.four_nibble()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericSizedIntArraysView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_one_nibble().ValueOr(false) &&
+        !has_one_nibble().ValueOr(false))
+      return false;
+    if (has_one_nibble().ValueOr(false) &&
+        !emboss_reserved_local_other.has_one_nibble().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_one_nibble().ValueOr(false) &&
+        has_one_nibble().ValueOr(false) &&
+        !one_nibble().UncheckedEquals(emboss_reserved_local_other.one_nibble()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_two_nibble().ValueOr(false) &&
+        !has_two_nibble().ValueOr(false))
+      return false;
+    if (has_two_nibble().ValueOr(false) &&
+        !emboss_reserved_local_other.has_two_nibble().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_two_nibble().ValueOr(false) &&
+        has_two_nibble().ValueOr(false) &&
+        !two_nibble().UncheckedEquals(emboss_reserved_local_other.two_nibble()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_four_nibble().ValueOr(false) &&
+        !has_four_nibble().ValueOr(false))
+      return false;
+    if (has_four_nibble().ValueOr(false) &&
+        !emboss_reserved_local_other.has_four_nibble().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_four_nibble().ValueOr(false) &&
+        has_four_nibble().ValueOr(false) &&
+        !four_nibble().UncheckedEquals(emboss_reserved_local_other.four_nibble()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericSizedIntArraysView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericSizedIntArraysView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericSizedIntArraysView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "one_nibble") {
+        if (!one_nibble().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "two_nibble") {
+        if (!two_nibble().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "four_nibble") {
+        if (!four_nibble().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_one_nibble().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          one_nibble().IsAggregate() || one_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("one_nibble: ");
+        one_nibble().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !one_nibble().IsAggregate() && !one_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# one_nibble: UNREADABLE\n");
+      }
+    }
+
+    if (has_two_nibble().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          two_nibble().IsAggregate() || two_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("two_nibble: ");
+        two_nibble().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !two_nibble().IsAggregate() && !two_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# two_nibble: UNREADABLE\n");
+      }
+    }
+
+    if (has_four_nibble().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          four_nibble().IsAggregate() || four_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("four_nibble: ");
+        four_nibble().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !four_nibble().IsAggregate() && !four_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# four_nibble: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/4, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 4,
+    1 >
+
+ one_nibble() const;
+  ::emboss::support::Maybe<bool> has_one_nibble() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 8>::template OffsetStorageType</**/8, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 8>, 8,
+    1 >
+
+ two_nibble() const;
+  ::emboss::support::Maybe<bool> has_two_nibble() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 24>::template OffsetStorageType</**/16, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 24>, 16,
+    1 >
+
+ four_nibble() const;
+  ::emboss::support::Maybe<bool> has_four_nibble() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView IntrinsicSizeInBits() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBitsView() {}
+    EmbossReservedDollarVirtualMaxSizeInBitsView(const EmbossReservedDollarVirtualMaxSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView(EmbossReservedDollarVirtualMaxSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(const EmbossReservedDollarVirtualMaxSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(EmbossReservedDollarVirtualMaxSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBitsView MaxSizeInBits() {
+    return EmbossReservedDollarVirtualMaxSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBitsView() {}
+    EmbossReservedDollarVirtualMinSizeInBitsView(const EmbossReservedDollarVirtualMinSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView(EmbossReservedDollarVirtualMinSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(const EmbossReservedDollarVirtualMinSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(EmbossReservedDollarVirtualMinSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBitsView MinSizeInBits() {
+    return EmbossReservedDollarVirtualMinSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericSizedIntArraysView;
+};
+using SizedIntArraysView =
+    GenericSizedIntArraysView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using SizedIntArraysWriter =
+    GenericSizedIntArraysView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericSizedIntArraysView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericSizedIntArraysView<
+    GenericSizedIntArraysView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericSizedIntArraysView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeSizedIntArraysView( T &&emboss_reserved_local_arg) {
+  return GenericSizedIntArraysView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericSizedIntArraysView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeSizedIntArraysView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericSizedIntArraysView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericSizedIntArraysView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedSizedIntArraysView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericSizedIntArraysView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace SizedEnumArrays {
+
+}  // namespace SizedEnumArrays
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericSizedEnumArraysView;
+
+template <class Storage>
+class GenericSizedEnumArraysView final {
+ public:
+  GenericSizedEnumArraysView() : backing_() {}
+  explicit GenericSizedEnumArraysView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericSizedEnumArraysView(
+      const GenericSizedEnumArraysView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericSizedEnumArraysView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericSizedEnumArraysView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericSizedEnumArraysView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericSizedEnumArraysView<Storage> &operator=(
+      const GenericSizedEnumArraysView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_one_nibble().Known()) return false;
+    if (has_one_nibble().ValueOrDefault() && !one_nibble().Ok()) return false;
+
+
+    if (!has_two_nibble().Known()) return false;
+    if (has_two_nibble().ValueOrDefault() && !two_nibble().Ok()) return false;
+
+
+    if (!has_four_nibble().Known()) return false;
+    if (has_four_nibble().ValueOrDefault() && !four_nibble().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBits().Known()) return false;
+    if (has_IntrinsicSizeInBits().ValueOrDefault() && !IntrinsicSizeInBits().Ok()) return false;
+
+
+    if (!has_MaxSizeInBits().Known()) return false;
+    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok()) return false;
+
+
+    if (!has_MinSizeInBits().Known()) return false;
+    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBits().Ok() &&
+           backing_.SizeInBits() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBits().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBits() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBits().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBits().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericSizedEnumArraysView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_one_nibble().Known()) return false;
+    if (!emboss_reserved_local_other.has_one_nibble().Known()) return false;
+
+    if (emboss_reserved_local_other.has_one_nibble().ValueOrDefault() &&
+        !has_one_nibble().ValueOrDefault())
+      return false;
+    if (has_one_nibble().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_one_nibble().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_one_nibble().ValueOrDefault() &&
+        has_one_nibble().ValueOrDefault() &&
+        !one_nibble().Equals(emboss_reserved_local_other.one_nibble()))
+      return false;
+
+
+
+    if (!has_two_nibble().Known()) return false;
+    if (!emboss_reserved_local_other.has_two_nibble().Known()) return false;
+
+    if (emboss_reserved_local_other.has_two_nibble().ValueOrDefault() &&
+        !has_two_nibble().ValueOrDefault())
+      return false;
+    if (has_two_nibble().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_two_nibble().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_two_nibble().ValueOrDefault() &&
+        has_two_nibble().ValueOrDefault() &&
+        !two_nibble().Equals(emboss_reserved_local_other.two_nibble()))
+      return false;
+
+
+
+    if (!has_four_nibble().Known()) return false;
+    if (!emboss_reserved_local_other.has_four_nibble().Known()) return false;
+
+    if (emboss_reserved_local_other.has_four_nibble().ValueOrDefault() &&
+        !has_four_nibble().ValueOrDefault())
+      return false;
+    if (has_four_nibble().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_four_nibble().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_four_nibble().ValueOrDefault() &&
+        has_four_nibble().ValueOrDefault() &&
+        !four_nibble().Equals(emboss_reserved_local_other.four_nibble()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericSizedEnumArraysView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_one_nibble().ValueOr(false) &&
+        !has_one_nibble().ValueOr(false))
+      return false;
+    if (has_one_nibble().ValueOr(false) &&
+        !emboss_reserved_local_other.has_one_nibble().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_one_nibble().ValueOr(false) &&
+        has_one_nibble().ValueOr(false) &&
+        !one_nibble().UncheckedEquals(emboss_reserved_local_other.one_nibble()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_two_nibble().ValueOr(false) &&
+        !has_two_nibble().ValueOr(false))
+      return false;
+    if (has_two_nibble().ValueOr(false) &&
+        !emboss_reserved_local_other.has_two_nibble().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_two_nibble().ValueOr(false) &&
+        has_two_nibble().ValueOr(false) &&
+        !two_nibble().UncheckedEquals(emboss_reserved_local_other.two_nibble()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_four_nibble().ValueOr(false) &&
+        !has_four_nibble().ValueOr(false))
+      return false;
+    if (has_four_nibble().ValueOr(false) &&
+        !emboss_reserved_local_other.has_four_nibble().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_four_nibble().ValueOr(false) &&
+        has_four_nibble().ValueOr(false) &&
+        !four_nibble().UncheckedEquals(emboss_reserved_local_other.four_nibble()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericSizedEnumArraysView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericSizedEnumArraysView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericSizedEnumArraysView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "one_nibble") {
+        if (!one_nibble().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "two_nibble") {
+        if (!two_nibble().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "four_nibble") {
+        if (!four_nibble().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_one_nibble().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          one_nibble().IsAggregate() || one_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("one_nibble: ");
+        one_nibble().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !one_nibble().IsAggregate() && !one_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# one_nibble: UNREADABLE\n");
+      }
+    }
+
+    if (has_two_nibble().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          two_nibble().IsAggregate() || two_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("two_nibble: ");
+        two_nibble().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !two_nibble().IsAggregate() && !two_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# two_nibble: UNREADABLE\n");
+      }
+    }
+
+    if (has_four_nibble().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          four_nibble().IsAggregate() || four_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("four_nibble: ");
+        four_nibble().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !four_nibble().IsAggregate() && !four_nibble().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# four_nibble: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/4, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 4,
+    1 >
+
+ one_nibble() const;
+  ::emboss::support::Maybe<bool> has_one_nibble() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 8>::template OffsetStorageType</**/8, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 8>, 8,
+    1 >
+
+ two_nibble() const;
+  ::emboss::support::Maybe<bool> has_two_nibble() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 24>::template OffsetStorageType</**/16, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 24>, 16,
+    1 >
+
+ four_nibble() const;
+  ::emboss::support::Maybe<bool> has_four_nibble() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView IntrinsicSizeInBits() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBitsView() {}
+    EmbossReservedDollarVirtualMaxSizeInBitsView(const EmbossReservedDollarVirtualMaxSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView(EmbossReservedDollarVirtualMaxSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(const EmbossReservedDollarVirtualMaxSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(EmbossReservedDollarVirtualMaxSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBitsView MaxSizeInBits() {
+    return EmbossReservedDollarVirtualMaxSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBitsView() {}
+    EmbossReservedDollarVirtualMinSizeInBitsView(const EmbossReservedDollarVirtualMinSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView(EmbossReservedDollarVirtualMinSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(const EmbossReservedDollarVirtualMinSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(EmbossReservedDollarVirtualMinSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBitsView MinSizeInBits() {
+    return EmbossReservedDollarVirtualMinSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericSizedEnumArraysView;
+};
+using SizedEnumArraysView =
+    GenericSizedEnumArraysView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using SizedEnumArraysWriter =
+    GenericSizedEnumArraysView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericSizedEnumArraysView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericSizedEnumArraysView<
+    GenericSizedEnumArraysView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericSizedEnumArraysView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeSizedEnumArraysView( T &&emboss_reserved_local_arg) {
+  return GenericSizedEnumArraysView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericSizedEnumArraysView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeSizedEnumArraysView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericSizedEnumArraysView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericSizedEnumArraysView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedSizedEnumArraysView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericSizedEnumArraysView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+namespace BitArrayContainer {
+
+}  // namespace BitArrayContainer
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericBitArrayContainerView;
+
+template <class Storage>
+class GenericBitArrayContainerView final {
+ public:
+  GenericBitArrayContainerView() : backing_() {}
+  explicit GenericBitArrayContainerView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericBitArrayContainerView(
+      const GenericBitArrayContainerView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericBitArrayContainerView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericBitArrayContainerView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericBitArrayContainerView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericBitArrayContainerView<Storage> &operator=(
+      const GenericBitArrayContainerView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_uint_arrays().Known()) return false;
+    if (has_uint_arrays().ValueOrDefault() && !uint_arrays().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericBitArrayContainerView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_uint_arrays().Known()) return false;
+    if (!emboss_reserved_local_other.has_uint_arrays().Known()) return false;
+
+    if (emboss_reserved_local_other.has_uint_arrays().ValueOrDefault() &&
+        !has_uint_arrays().ValueOrDefault())
+      return false;
+    if (has_uint_arrays().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_uint_arrays().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_uint_arrays().ValueOrDefault() &&
+        has_uint_arrays().ValueOrDefault() &&
+        !uint_arrays().Equals(emboss_reserved_local_other.uint_arrays()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericBitArrayContainerView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_uint_arrays().ValueOr(false) &&
+        !has_uint_arrays().ValueOr(false))
+      return false;
+    if (has_uint_arrays().ValueOr(false) &&
+        !emboss_reserved_local_other.has_uint_arrays().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_uint_arrays().ValueOr(false) &&
+        has_uint_arrays().ValueOr(false) &&
+        !uint_arrays().UncheckedEquals(emboss_reserved_local_other.uint_arrays()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericBitArrayContainerView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericBitArrayContainerView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericBitArrayContainerView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "uint_arrays") {
+        if (!uint_arrays().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_uint_arrays().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          uint_arrays().IsAggregate() || uint_arrays().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("uint_arrays: ");
+        uint_arrays().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !uint_arrays().IsAggregate() && !uint_arrays().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# uint_arrays: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::test::GenericSizedUIntArraysView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 56>>
+
+ uint_arrays() const;
+  ::emboss::support::Maybe<bool> has_uint_arrays() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericBitArrayContainerView;
+};
+using BitArrayContainerView =
+    GenericBitArrayContainerView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using BitArrayContainerWriter =
+    GenericBitArrayContainerView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericBitArrayContainerView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericBitArrayContainerView<
+    GenericBitArrayContainerView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericBitArrayContainerView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeBitArrayContainerView( T &&emboss_reserved_local_arg) {
+  return GenericBitArrayContainerView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericBitArrayContainerView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeBitArrayContainerView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericBitArrayContainerView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericBitArrayContainerView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedBitArrayContainerView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericBitArrayContainerView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+enum class Enum : ::std::uint64_t {
+  VALUE1 = static_cast</**/::std::int32_t>(1LL),
+  VALUE10 = static_cast</**/::std::int32_t>(10LL),
+  VALUE100 = static_cast</**/::std::int32_t>(100LL),
+  VALUE1000 = static_cast</**/::std::int32_t>(1000LL),
+  VALUE10000 = static_cast</**/::std::int32_t>(10000LL),
+  VALUE100000 = static_cast</**/::std::int32_t>(100000LL),
+  VALUE1000000 = static_cast</**/::std::int32_t>(1000000LL),
+  VALUE10000000 = static_cast</**/::std::int32_t>(10000000LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<Enum> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   Enum *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("VALUE1", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Enum::VALUE1;
+      return true;
+    }
+
+    if (!strcmp("VALUE10", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Enum::VALUE10;
+      return true;
+    }
+
+    if (!strcmp("VALUE100", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Enum::VALUE100;
+      return true;
+    }
+
+    if (!strcmp("VALUE1000", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Enum::VALUE1000;
+      return true;
+    }
+
+    if (!strcmp("VALUE10000", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Enum::VALUE10000;
+      return true;
+    }
+
+    if (!strcmp("VALUE100000", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Enum::VALUE100000;
+      return true;
+    }
+
+    if (!strcmp("VALUE1000000", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Enum::VALUE1000000;
+      return true;
+    }
+
+    if (!strcmp("VALUE10000000", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Enum::VALUE10000000;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      Enum emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Enum::VALUE1: return "VALUE1";
+
+      case Enum::VALUE10: return "VALUE10";
+
+      case Enum::VALUE100: return "VALUE100";
+
+      case Enum::VALUE1000: return "VALUE1000";
+
+      case Enum::VALUE10000: return "VALUE10000";
+
+      case Enum::VALUE100000: return "VALUE100000";
+
+      case Enum::VALUE1000000: return "VALUE1000000";
+
+      case Enum::VALUE10000000: return "VALUE10000000";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(Enum emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Enum::VALUE1: return true;
+
+      case Enum::VALUE10: return true;
+
+      case Enum::VALUE100: return true;
+
+      case Enum::VALUE1000: return true;
+
+      case Enum::VALUE10000: return true;
+
+      case Enum::VALUE100000: return true;
+
+      case Enum::VALUE1000000: return true;
+
+      case Enum::VALUE10000000: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       Enum emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<Enum>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    Enum *emboss_reserved_local_result) {
+  return EnumTraits<Enum>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    Enum emboss_reserved_local_value) {
+  return EnumTraits<Enum>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(Enum emboss_reserved_local_value) {
+  return EnumTraits<Enum>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    Enum emboss_reserved_local_value) {
+  return EnumTraits<Enum>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+
+namespace SizedUIntArrays {
+
+}  // namespace SizedUIntArrays
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/4, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 4,
+    1 >
+
+ GenericSizedUIntArraysView<Storage>::one_nibble()
+    const {
+
+  if ( has_one_nibble().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/4, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 4,
+    1 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/4, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 4,
+    1 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizedUIntArraysView<Storage>::has_one_nibble() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 8>::template OffsetStorageType</**/8, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 8>, 8,
+    1 >
+
+ GenericSizedUIntArraysView<Storage>::two_nibble()
+    const {
+
+  if ( has_two_nibble().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(16LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 8>::template OffsetStorageType</**/8, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 8>, 8,
+    1 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   8>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 8>::template OffsetStorageType</**/8, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 8>, 8,
+    1 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizedUIntArraysView<Storage>::has_two_nibble() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 24>::template OffsetStorageType</**/16, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 24>, 16,
+    1 >
+
+ GenericSizedUIntArraysView<Storage>::four_nibble()
+    const {
+
+  if ( has_four_nibble().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(32LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(24LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 24>::template OffsetStorageType</**/16, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 24>, 16,
+    1 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   24>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 24>::template OffsetStorageType</**/16, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 24>, 16,
+    1 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizedUIntArraysView<Storage>::has_four_nibble() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace SizedUIntArrays {
+inline constexpr ::std::int32_t IntrinsicSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(56LL)).ValueOrDefault();
+}
+}  // namespace SizedUIntArrays
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizedUIntArraysView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
+  return SizedUIntArrays::IntrinsicSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizedUIntArraysView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
+  return SizedUIntArrays::IntrinsicSizeInBits();
+}
+
+namespace SizedUIntArrays {
+inline constexpr ::std::int32_t MaxSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(56LL)).ValueOrDefault();
+}
+}  // namespace SizedUIntArrays
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizedUIntArraysView<Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
+  return SizedUIntArrays::MaxSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizedUIntArraysView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
+  return SizedUIntArrays::MaxSizeInBits();
+}
+
+namespace SizedUIntArrays {
+inline constexpr ::std::int32_t MinSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(56LL)).ValueOrDefault();
+}
+}  // namespace SizedUIntArrays
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizedUIntArraysView<Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
+  return SizedUIntArrays::MinSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizedUIntArraysView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
+  return SizedUIntArrays::MinSizeInBits();
+}
+namespace SizedIntArrays {
+
+}  // namespace SizedIntArrays
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/4, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 4,
+    1 >
+
+ GenericSizedIntArraysView<Storage>::one_nibble()
+    const {
+
+  if ( has_one_nibble().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/4, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 4,
+    1 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/4, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 4,
+    1 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizedIntArraysView<Storage>::has_one_nibble() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 8>::template OffsetStorageType</**/8, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 8>, 8,
+    1 >
+
+ GenericSizedIntArraysView<Storage>::two_nibble()
+    const {
+
+  if ( has_two_nibble().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(16LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 8>::template OffsetStorageType</**/8, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 8>, 8,
+    1 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   8>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 8>::template OffsetStorageType</**/8, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 8>, 8,
+    1 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizedIntArraysView<Storage>::has_two_nibble() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 24>::template OffsetStorageType</**/16, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 24>, 16,
+    1 >
+
+ GenericSizedIntArraysView<Storage>::four_nibble()
+    const {
+
+  if ( has_four_nibble().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(32LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(24LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 24>::template OffsetStorageType</**/16, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 24>, 16,
+    1 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   24>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 24>::template OffsetStorageType</**/16, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 24>, 16,
+    1 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizedIntArraysView<Storage>::has_four_nibble() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace SizedIntArrays {
+inline constexpr ::std::int32_t IntrinsicSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(56LL)).ValueOrDefault();
+}
+}  // namespace SizedIntArrays
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizedIntArraysView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
+  return SizedIntArrays::IntrinsicSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizedIntArraysView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
+  return SizedIntArrays::IntrinsicSizeInBits();
+}
+
+namespace SizedIntArrays {
+inline constexpr ::std::int32_t MaxSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(56LL)).ValueOrDefault();
+}
+}  // namespace SizedIntArrays
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizedIntArraysView<Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
+  return SizedIntArrays::MaxSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizedIntArraysView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
+  return SizedIntArrays::MaxSizeInBits();
+}
+
+namespace SizedIntArrays {
+inline constexpr ::std::int32_t MinSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(56LL)).ValueOrDefault();
+}
+}  // namespace SizedIntArrays
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizedIntArraysView<Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
+  return SizedIntArrays::MinSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizedIntArraysView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
+  return SizedIntArrays::MinSizeInBits();
+}
+namespace SizedEnumArrays {
+
+}  // namespace SizedEnumArrays
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/4, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 4,
+    1 >
+
+ GenericSizedEnumArraysView<Storage>::one_nibble()
+    const {
+
+  if ( has_one_nibble().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/4, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 4,
+    1 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<4, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/4, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 4,
+    1 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizedEnumArraysView<Storage>::has_one_nibble() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 8>::template OffsetStorageType</**/8, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 8>, 8,
+    1 >
+
+ GenericSizedEnumArraysView<Storage>::two_nibble()
+    const {
+
+  if ( has_two_nibble().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(16LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 8>::template OffsetStorageType</**/8, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 8>, 8,
+    1 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   8>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 8>::template OffsetStorageType</**/8, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 8>, 8,
+    1 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizedEnumArraysView<Storage>::has_two_nibble() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 24>::template OffsetStorageType</**/16, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 24>, 16,
+    1 >
+
+ GenericSizedEnumArraysView<Storage>::four_nibble()
+    const {
+
+  if ( has_four_nibble().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(32LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(24LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 24>::template OffsetStorageType</**/16, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 24>, 16,
+    1 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   24>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 24>::template OffsetStorageType</**/16, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 24>, 16,
+    1 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizedEnumArraysView<Storage>::has_four_nibble() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace SizedEnumArrays {
+inline constexpr ::std::int32_t IntrinsicSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(56LL)).ValueOrDefault();
+}
+}  // namespace SizedEnumArrays
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizedEnumArraysView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
+  return SizedEnumArrays::IntrinsicSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizedEnumArraysView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
+  return SizedEnumArrays::IntrinsicSizeInBits();
+}
+
+namespace SizedEnumArrays {
+inline constexpr ::std::int32_t MaxSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(56LL)).ValueOrDefault();
+}
+}  // namespace SizedEnumArrays
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizedEnumArraysView<Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
+  return SizedEnumArrays::MaxSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizedEnumArraysView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
+  return SizedEnumArrays::MaxSizeInBits();
+}
+
+namespace SizedEnumArrays {
+inline constexpr ::std::int32_t MinSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(56LL)).ValueOrDefault();
+}
+}  // namespace SizedEnumArrays
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizedEnumArraysView<Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
+  return SizedEnumArrays::MinSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizedEnumArraysView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
+  return SizedEnumArrays::MinSizeInBits();
+}
+namespace BitArrayContainer {
+
+}  // namespace BitArrayContainer
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericSizedUIntArraysView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 56>>
+
+ GenericBitArrayContainerView<Storage>::uint_arrays()
+    const {
+
+  if ( has_uint_arrays().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(7LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericSizedUIntArraysView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 56>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericSizedUIntArraysView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 56>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBitArrayContainerView<Storage>::has_uint_arrays() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace BitArrayContainer {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(7LL)).ValueOrDefault();
+}
+}  // namespace BitArrayContainer
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBitArrayContainerView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return BitArrayContainer::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBitArrayContainerView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return BitArrayContainer::IntrinsicSizeInBytes();
+}
+
+namespace BitArrayContainer {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(7LL)).ValueOrDefault();
+}
+}  // namespace BitArrayContainer
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBitArrayContainerView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return BitArrayContainer::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBitArrayContainerView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return BitArrayContainer::MaxSizeInBytes();
+}
+
+namespace BitArrayContainer {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(7LL)).ValueOrDefault();
+}
+}  // namespace BitArrayContainer
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBitArrayContainerView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return BitArrayContainer::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBitArrayContainerView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return BitArrayContainer::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_EXPLICIT_SIZES_EMB_H_
+
diff --git a/testdata/golden_cpp/float.emb.h b/testdata/golden_cpp/float.emb.h
new file mode 100644
index 0000000..d43d32e
--- /dev/null
+++ b/testdata/golden_cpp/float.emb.h
@@ -0,0 +1,1348 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_FLOAT_EMB_H_
+#define TESTDATA_FLOAT_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace Floats {
+
+}  // namespace Floats
+
+
+template <class Storage>
+class GenericFloatsView;
+
+namespace Doubles {
+
+}  // namespace Doubles
+
+
+template <class Storage>
+class GenericDoublesView;
+
+
+
+
+
+
+namespace Floats {
+
+}  // namespace Floats
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericFloatsView;
+
+template <class Storage>
+class GenericFloatsView final {
+ public:
+  GenericFloatsView() : backing_() {}
+  explicit GenericFloatsView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericFloatsView(
+      const GenericFloatsView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericFloatsView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericFloatsView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericFloatsView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericFloatsView<Storage> &operator=(
+      const GenericFloatsView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_float_little_endian().Known()) return false;
+    if (has_float_little_endian().ValueOrDefault() && !float_little_endian().Ok()) return false;
+
+
+    if (!has_float_big_endian().Known()) return false;
+    if (has_float_big_endian().ValueOrDefault() && !float_big_endian().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericFloatsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_float_little_endian().Known()) return false;
+    if (!emboss_reserved_local_other.has_float_little_endian().Known()) return false;
+
+    if (emboss_reserved_local_other.has_float_little_endian().ValueOrDefault() &&
+        !has_float_little_endian().ValueOrDefault())
+      return false;
+    if (has_float_little_endian().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_float_little_endian().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_float_little_endian().ValueOrDefault() &&
+        has_float_little_endian().ValueOrDefault() &&
+        !float_little_endian().Equals(emboss_reserved_local_other.float_little_endian()))
+      return false;
+
+
+
+    if (!has_float_big_endian().Known()) return false;
+    if (!emboss_reserved_local_other.has_float_big_endian().Known()) return false;
+
+    if (emboss_reserved_local_other.has_float_big_endian().ValueOrDefault() &&
+        !has_float_big_endian().ValueOrDefault())
+      return false;
+    if (has_float_big_endian().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_float_big_endian().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_float_big_endian().ValueOrDefault() &&
+        has_float_big_endian().ValueOrDefault() &&
+        !float_big_endian().Equals(emboss_reserved_local_other.float_big_endian()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericFloatsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_float_little_endian().ValueOr(false) &&
+        !has_float_little_endian().ValueOr(false))
+      return false;
+    if (has_float_little_endian().ValueOr(false) &&
+        !emboss_reserved_local_other.has_float_little_endian().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_float_little_endian().ValueOr(false) &&
+        has_float_little_endian().ValueOr(false) &&
+        !float_little_endian().UncheckedEquals(emboss_reserved_local_other.float_little_endian()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_float_big_endian().ValueOr(false) &&
+        !has_float_big_endian().ValueOr(false))
+      return false;
+    if (has_float_big_endian().ValueOr(false) &&
+        !emboss_reserved_local_other.has_float_big_endian().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_float_big_endian().ValueOr(false) &&
+        has_float_big_endian().ValueOr(false) &&
+        !float_big_endian().UncheckedEquals(emboss_reserved_local_other.float_big_endian()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericFloatsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericFloatsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericFloatsView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "float_little_endian") {
+        if (!float_little_endian().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "float_big_endian") {
+        if (!float_big_endian().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_float_little_endian().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          float_little_endian().IsAggregate() || float_little_endian().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("float_little_endian: ");
+        float_little_endian().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !float_little_endian().IsAggregate() && !float_little_endian().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# float_little_endian: UNREADABLE\n");
+      }
+    }
+
+    if (has_float_big_endian().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          float_big_endian().IsAggregate() || float_big_endian().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("float_big_endian: ");
+        float_big_endian().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !float_big_endian().IsAggregate() && !float_big_endian().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# float_big_endian: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::FloatView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ float_little_endian() const;
+  ::emboss::support::Maybe<bool> has_float_little_endian() const;
+
+ public:
+  typename ::emboss::prelude::FloatView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+ float_big_endian() const;
+  ::emboss::support::Maybe<bool> has_float_big_endian() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericFloatsView;
+};
+using FloatsView =
+    GenericFloatsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using FloatsWriter =
+    GenericFloatsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericFloatsView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericFloatsView<
+    GenericFloatsView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericFloatsView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeFloatsView( T &&emboss_reserved_local_arg) {
+  return GenericFloatsView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericFloatsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeFloatsView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericFloatsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericFloatsView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedFloatsView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericFloatsView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace Doubles {
+
+}  // namespace Doubles
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericDoublesView;
+
+template <class Storage>
+class GenericDoublesView final {
+ public:
+  GenericDoublesView() : backing_() {}
+  explicit GenericDoublesView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericDoublesView(
+      const GenericDoublesView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericDoublesView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericDoublesView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericDoublesView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericDoublesView<Storage> &operator=(
+      const GenericDoublesView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_double_little_endian().Known()) return false;
+    if (has_double_little_endian().ValueOrDefault() && !double_little_endian().Ok()) return false;
+
+
+    if (!has_double_big_endian().Known()) return false;
+    if (has_double_big_endian().ValueOrDefault() && !double_big_endian().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericDoublesView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_double_little_endian().Known()) return false;
+    if (!emboss_reserved_local_other.has_double_little_endian().Known()) return false;
+
+    if (emboss_reserved_local_other.has_double_little_endian().ValueOrDefault() &&
+        !has_double_little_endian().ValueOrDefault())
+      return false;
+    if (has_double_little_endian().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_double_little_endian().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_double_little_endian().ValueOrDefault() &&
+        has_double_little_endian().ValueOrDefault() &&
+        !double_little_endian().Equals(emboss_reserved_local_other.double_little_endian()))
+      return false;
+
+
+
+    if (!has_double_big_endian().Known()) return false;
+    if (!emboss_reserved_local_other.has_double_big_endian().Known()) return false;
+
+    if (emboss_reserved_local_other.has_double_big_endian().ValueOrDefault() &&
+        !has_double_big_endian().ValueOrDefault())
+      return false;
+    if (has_double_big_endian().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_double_big_endian().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_double_big_endian().ValueOrDefault() &&
+        has_double_big_endian().ValueOrDefault() &&
+        !double_big_endian().Equals(emboss_reserved_local_other.double_big_endian()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericDoublesView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_double_little_endian().ValueOr(false) &&
+        !has_double_little_endian().ValueOr(false))
+      return false;
+    if (has_double_little_endian().ValueOr(false) &&
+        !emboss_reserved_local_other.has_double_little_endian().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_double_little_endian().ValueOr(false) &&
+        has_double_little_endian().ValueOr(false) &&
+        !double_little_endian().UncheckedEquals(emboss_reserved_local_other.double_little_endian()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_double_big_endian().ValueOr(false) &&
+        !has_double_big_endian().ValueOr(false))
+      return false;
+    if (has_double_big_endian().ValueOr(false) &&
+        !emboss_reserved_local_other.has_double_big_endian().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_double_big_endian().ValueOr(false) &&
+        has_double_big_endian().ValueOr(false) &&
+        !double_big_endian().UncheckedEquals(emboss_reserved_local_other.double_big_endian()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericDoublesView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericDoublesView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericDoublesView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "double_little_endian") {
+        if (!double_little_endian().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "double_big_endian") {
+        if (!double_big_endian().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_double_little_endian().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          double_little_endian().IsAggregate() || double_little_endian().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("double_little_endian: ");
+        double_little_endian().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !double_little_endian().IsAggregate() && !double_little_endian().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# double_little_endian: UNREADABLE\n");
+      }
+    }
+
+    if (has_double_big_endian().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          double_big_endian().IsAggregate() || double_big_endian().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("double_big_endian: ");
+        double_big_endian().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !double_big_endian().IsAggregate() && !double_big_endian().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# double_big_endian: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::FloatView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 64>>
+
+ double_little_endian() const;
+  ::emboss::support::Maybe<bool> has_double_little_endian() const;
+
+ public:
+  typename ::emboss::prelude::FloatView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 8>>, 64>>
+
+ double_big_endian() const;
+  ::emboss::support::Maybe<bool> has_double_big_endian() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericDoublesView;
+};
+using DoublesView =
+    GenericDoublesView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using DoublesWriter =
+    GenericDoublesView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericDoublesView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericDoublesView<
+    GenericDoublesView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericDoublesView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeDoublesView( T &&emboss_reserved_local_arg) {
+  return GenericDoublesView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericDoublesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeDoublesView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericDoublesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericDoublesView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedDoublesView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericDoublesView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace Floats {
+
+}  // namespace Floats
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FloatView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ GenericFloatsView<Storage>::float_little_endian()
+    const {
+
+  if ( has_float_little_endian().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FloatView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FloatView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericFloatsView<Storage>::has_float_little_endian() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FloatView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+ GenericFloatsView<Storage>::float_big_endian()
+    const {
+
+  if ( has_float_big_endian().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FloatView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   4>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FloatView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericFloatsView<Storage>::has_float_big_endian() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Floats {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace Floats
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFloatsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Floats::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFloatsView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Floats::IntrinsicSizeInBytes();
+}
+
+namespace Floats {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace Floats
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFloatsView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Floats::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFloatsView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Floats::MaxSizeInBytes();
+}
+
+namespace Floats {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace Floats
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFloatsView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Floats::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFloatsView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Floats::MinSizeInBytes();
+}
+namespace Doubles {
+
+}  // namespace Doubles
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FloatView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 64>>
+
+ GenericDoublesView<Storage>::double_little_endian()
+    const {
+
+  if ( has_double_little_endian().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FloatView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 64>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FloatView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 64>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericDoublesView<Storage>::has_double_little_endian() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FloatView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 8>>, 64>>
+
+ GenericDoublesView<Storage>::double_big_endian()
+    const {
+
+  if ( has_double_big_endian().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FloatView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 8>>, 64>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   8>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FloatView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 8>>, 64>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericDoublesView<Storage>::has_double_big_endian() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Doubles {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(16LL)).ValueOrDefault();
+}
+}  // namespace Doubles
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericDoublesView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Doubles::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericDoublesView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Doubles::IntrinsicSizeInBytes();
+}
+
+namespace Doubles {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(16LL)).ValueOrDefault();
+}
+}  // namespace Doubles
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericDoublesView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Doubles::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericDoublesView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Doubles::MaxSizeInBytes();
+}
+
+namespace Doubles {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(16LL)).ValueOrDefault();
+}
+}  // namespace Doubles
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericDoublesView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Doubles::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericDoublesView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Doubles::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_FLOAT_EMB_H_
+
diff --git a/testdata/golden_cpp/generate_golden_files.sh b/testdata/golden_cpp/generate_golden_files.sh
new file mode 100755
index 0000000..97f2ae6
--- /dev/null
+++ b/testdata/golden_cpp/generate_golden_files.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+set -e
+set -x
+
+# Bazel sets TEST_TMPDIR to a temporary directory for the test to use.
+readonly GEN_DIR="$TEST_TMPDIR/generated_headers"
+mkdir -p "$GEN_DIR"
+
+# The script's working directory is the root of the runfiles tree.
+# All data dependencies are available at their workspace-relative paths.
+export PYTHONPATH=.
+
+for emb_file in $(find testdata -maxdepth 1 -name "*.emb" -not -name "importer.emb" -not -name "importer2.emb" -not -name "imported_genfiles.emb"); do
+  base_name=$(basename "$emb_file")
+  ir_file="$TEST_TMPDIR/${base_name}.ir.json"
+  h_file="$GEN_DIR/${base_name}.h"
+
+  # Run the compiler.
+  python3 compiler/front_end/emboss_front_end.py --output-file "$ir_file" "$emb_file"
+  python3 compiler/back_end/cpp/emboss_codegen_cpp.py --input-file "$ir_file" --output-file "$h_file"
+done
+
+# Compare the generated files with the golden files.
+echo "Comparing generated files to golden files..."
+diff --brief --recursive --strip-trailing-cr --exclude="generate_golden_files.sh" "$GEN_DIR" "testdata/golden_cpp"
diff --git a/testdata/golden_cpp/imported.emb.h b/testdata/golden_cpp/imported.emb.h
new file mode 100644
index 0000000..2217543
--- /dev/null
+++ b/testdata/golden_cpp/imported.emb.h
@@ -0,0 +1,571 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_IMPORTED_EMB_H_
+#define TESTDATA_IMPORTED_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace Inner {
+
+}  // namespace Inner
+
+
+template <class Storage>
+class GenericInnerView;
+
+
+
+
+
+namespace Inner {
+
+}  // namespace Inner
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericInnerView;
+
+template <class Storage>
+class GenericInnerView final {
+ public:
+  GenericInnerView() : backing_() {}
+  explicit GenericInnerView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericInnerView(
+      const GenericInnerView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericInnerView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericInnerView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericInnerView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericInnerView<Storage> &operator=(
+      const GenericInnerView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_value().Known()) return false;
+    if (has_value().ValueOrDefault() && !value().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericInnerView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_value().Known()) return false;
+    if (!emboss_reserved_local_other.has_value().Known()) return false;
+
+    if (emboss_reserved_local_other.has_value().ValueOrDefault() &&
+        !has_value().ValueOrDefault())
+      return false;
+    if (has_value().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_value().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_value().ValueOrDefault() &&
+        has_value().ValueOrDefault() &&
+        !value().Equals(emboss_reserved_local_other.value()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericInnerView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_value().ValueOr(false) &&
+        !has_value().ValueOr(false))
+      return false;
+    if (has_value().ValueOr(false) &&
+        !emboss_reserved_local_other.has_value().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_value().ValueOr(false) &&
+        has_value().ValueOr(false) &&
+        !value().UncheckedEquals(emboss_reserved_local_other.value()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericInnerView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericInnerView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericInnerView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "value") {
+        if (!value().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_value().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          value().IsAggregate() || value().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("value: ");
+        value().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !value().IsAggregate() && !value().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# value: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 64>>
+
+ value() const;
+  ::emboss::support::Maybe<bool> has_value() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericInnerView;
+};
+using InnerView =
+    GenericInnerView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using InnerWriter =
+    GenericInnerView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericInnerView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericInnerView<
+    GenericInnerView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericInnerView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeInnerView( T &&emboss_reserved_local_arg) {
+  return GenericInnerView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericInnerView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeInnerView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericInnerView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericInnerView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedInnerView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericInnerView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace Inner {
+
+}  // namespace Inner
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 64>>
+
+ GenericInnerView<Storage>::value()
+    const {
+
+  if ( has_value().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 64>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 64>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericInnerView<Storage>::has_value() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Inner {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace Inner
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericInnerView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Inner::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericInnerView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Inner::IntrinsicSizeInBytes();
+}
+
+namespace Inner {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace Inner
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericInnerView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Inner::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericInnerView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Inner::MaxSizeInBytes();
+}
+
+namespace Inner {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace Inner
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericInnerView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Inner::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericInnerView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Inner::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_IMPORTED_EMB_H_
+
diff --git a/testdata/golden_cpp/imported_genfiles.emb.h b/testdata/golden_cpp/imported_genfiles.emb.h
new file mode 100644
index 0000000..af1ef31
--- /dev/null
+++ b/testdata/golden_cpp/imported_genfiles.emb.h
@@ -0,0 +1,576 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_IMPORTED_GENFILES_EMB_H_
+#define TESTDATA_IMPORTED_GENFILES_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace generated {
+namespace Inner {
+
+}  // namespace Inner
+
+
+template <class Storage>
+class GenericInnerView;
+
+
+
+
+
+namespace Inner {
+
+}  // namespace Inner
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericInnerView;
+
+template <class Storage>
+class GenericInnerView final {
+ public:
+  GenericInnerView() : backing_() {}
+  explicit GenericInnerView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericInnerView(
+      const GenericInnerView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericInnerView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericInnerView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericInnerView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericInnerView<Storage> &operator=(
+      const GenericInnerView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_value().Known()) return false;
+    if (has_value().ValueOrDefault() && !value().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericInnerView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_value().Known()) return false;
+    if (!emboss_reserved_local_other.has_value().Known()) return false;
+
+    if (emboss_reserved_local_other.has_value().ValueOrDefault() &&
+        !has_value().ValueOrDefault())
+      return false;
+    if (has_value().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_value().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_value().ValueOrDefault() &&
+        has_value().ValueOrDefault() &&
+        !value().Equals(emboss_reserved_local_other.value()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericInnerView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_value().ValueOr(false) &&
+        !has_value().ValueOr(false))
+      return false;
+    if (has_value().ValueOr(false) &&
+        !emboss_reserved_local_other.has_value().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_value().ValueOr(false) &&
+        has_value().ValueOr(false) &&
+        !value().UncheckedEquals(emboss_reserved_local_other.value()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericInnerView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericInnerView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericInnerView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "value") {
+        if (!value().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_value().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          value().IsAggregate() || value().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("value: ");
+        value().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !value().IsAggregate() && !value().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# value: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 64>>
+
+ value() const;
+  ::emboss::support::Maybe<bool> has_value() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericInnerView;
+};
+using InnerView =
+    GenericInnerView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using InnerWriter =
+    GenericInnerView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericInnerView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericInnerView<
+    GenericInnerView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericInnerView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeInnerView( T &&emboss_reserved_local_arg) {
+  return GenericInnerView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericInnerView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeInnerView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericInnerView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericInnerView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedInnerView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericInnerView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace Inner {
+
+}  // namespace Inner
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 64>>
+
+ GenericInnerView<Storage>::value()
+    const {
+
+  if ( has_value().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 64>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 64>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericInnerView<Storage>::has_value() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Inner {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace Inner
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericInnerView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Inner::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericInnerView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Inner::IntrinsicSizeInBytes();
+}
+
+namespace Inner {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace Inner
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericInnerView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Inner::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericInnerView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Inner::MaxSizeInBytes();
+}
+
+namespace Inner {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace Inner
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericInnerView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Inner::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericInnerView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Inner::MinSizeInBytes();
+}
+
+
+
+}  // namespace generated
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_IMPORTED_GENFILES_EMB_H_
+
diff --git a/testdata/golden_cpp/importer.emb.h b/testdata/golden_cpp/importer.emb.h
new file mode 100644
index 0000000..75ad2d2
--- /dev/null
+++ b/testdata/golden_cpp/importer.emb.h
@@ -0,0 +1,683 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_IMPORTER_EMB_H_
+#define TESTDATA_IMPORTER_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+#include "testdata/imported.emb.h"
+
+#include "testdata/imported_genfiles.emb.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace Outer {
+
+}  // namespace Outer
+
+
+template <class Storage>
+class GenericOuterView;
+
+
+
+
+
+
+namespace Outer {
+
+}  // namespace Outer
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericOuterView;
+
+template <class Storage>
+class GenericOuterView final {
+ public:
+  GenericOuterView() : backing_() {}
+  explicit GenericOuterView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericOuterView(
+      const GenericOuterView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericOuterView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericOuterView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericOuterView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericOuterView<Storage> &operator=(
+      const GenericOuterView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_inner().Known()) return false;
+    if (has_inner().ValueOrDefault() && !inner().Ok()) return false;
+
+
+    if (!has_inner_gen().Known()) return false;
+    if (has_inner_gen().ValueOrDefault() && !inner_gen().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericOuterView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_inner().Known()) return false;
+    if (!emboss_reserved_local_other.has_inner().Known()) return false;
+
+    if (emboss_reserved_local_other.has_inner().ValueOrDefault() &&
+        !has_inner().ValueOrDefault())
+      return false;
+    if (has_inner().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_inner().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_inner().ValueOrDefault() &&
+        has_inner().ValueOrDefault() &&
+        !inner().Equals(emboss_reserved_local_other.inner()))
+      return false;
+
+
+
+    if (!has_inner_gen().Known()) return false;
+    if (!emboss_reserved_local_other.has_inner_gen().Known()) return false;
+
+    if (emboss_reserved_local_other.has_inner_gen().ValueOrDefault() &&
+        !has_inner_gen().ValueOrDefault())
+      return false;
+    if (has_inner_gen().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_inner_gen().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_inner_gen().ValueOrDefault() &&
+        has_inner_gen().ValueOrDefault() &&
+        !inner_gen().Equals(emboss_reserved_local_other.inner_gen()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericOuterView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_inner().ValueOr(false) &&
+        !has_inner().ValueOr(false))
+      return false;
+    if (has_inner().ValueOr(false) &&
+        !emboss_reserved_local_other.has_inner().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_inner().ValueOr(false) &&
+        has_inner().ValueOr(false) &&
+        !inner().UncheckedEquals(emboss_reserved_local_other.inner()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_inner_gen().ValueOr(false) &&
+        !has_inner_gen().ValueOr(false))
+      return false;
+    if (has_inner_gen().ValueOr(false) &&
+        !emboss_reserved_local_other.has_inner_gen().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_inner_gen().ValueOr(false) &&
+        has_inner_gen().ValueOr(false) &&
+        !inner_gen().UncheckedEquals(emboss_reserved_local_other.inner_gen()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericOuterView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericOuterView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericOuterView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "inner") {
+        if (!inner().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "inner_gen") {
+        if (!inner_gen().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_inner().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          inner().IsAggregate() || inner().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("inner: ");
+        inner().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !inner().IsAggregate() && !inner().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# inner: UNREADABLE\n");
+      }
+    }
+
+    if (has_inner_gen().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          inner_gen().IsAggregate() || inner_gen().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("inner_gen: ");
+        inner_gen().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !inner_gen().IsAggregate() && !inner_gen().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# inner_gen: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::test::GenericInnerView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ inner() const;
+  ::emboss::support::Maybe<bool> has_inner() const;
+
+ public:
+  typename ::emboss::test::generated::GenericInnerView<typename Storage::template OffsetStorageType</**/0, 8>>
+
+ inner_gen() const;
+  ::emboss::support::Maybe<bool> has_inner_gen() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericOuterView;
+};
+using OuterView =
+    GenericOuterView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using OuterWriter =
+    GenericOuterView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericOuterView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericOuterView<
+    GenericOuterView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericOuterView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeOuterView( T &&emboss_reserved_local_arg) {
+  return GenericOuterView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericOuterView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeOuterView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericOuterView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericOuterView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedOuterView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericOuterView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace Outer {
+
+}  // namespace Outer
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericInnerView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericOuterView<Storage>::inner()
+    const {
+
+  if ( has_inner().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericInnerView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericInnerView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericOuterView<Storage>::has_inner() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::generated::GenericInnerView<typename Storage::template OffsetStorageType</**/0, 8>>
+
+ GenericOuterView<Storage>::inner_gen()
+    const {
+
+  if ( has_inner_gen().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::generated::GenericInnerView<typename Storage::template OffsetStorageType</**/0, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   8>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::generated::GenericInnerView<typename Storage::template OffsetStorageType</**/0, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericOuterView<Storage>::has_inner_gen() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Outer {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(16LL)).ValueOrDefault();
+}
+}  // namespace Outer
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOuterView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Outer::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOuterView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Outer::IntrinsicSizeInBytes();
+}
+
+namespace Outer {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(16LL)).ValueOrDefault();
+}
+}  // namespace Outer
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOuterView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Outer::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOuterView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Outer::MaxSizeInBytes();
+}
+
+namespace Outer {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(16LL)).ValueOrDefault();
+}
+}  // namespace Outer
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOuterView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Outer::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOuterView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Outer::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_IMPORTER_EMB_H_
+
diff --git a/testdata/golden_cpp/importer2.emb.h b/testdata/golden_cpp/importer2.emb.h
new file mode 100644
index 0000000..ca22c93
--- /dev/null
+++ b/testdata/golden_cpp/importer2.emb.h
@@ -0,0 +1,565 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_IMPORTER2_EMB_H_
+#define TESTDATA_IMPORTER2_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+#include "testdata/importer.emb.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace Outer2 {
+
+}  // namespace Outer2
+
+
+template <class Storage>
+class GenericOuter2View;
+
+
+
+
+
+namespace Outer2 {
+
+}  // namespace Outer2
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericOuter2View;
+
+template <class Storage>
+class GenericOuter2View final {
+ public:
+  GenericOuter2View() : backing_() {}
+  explicit GenericOuter2View(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericOuter2View(
+      const GenericOuter2View<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericOuter2View<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericOuter2View(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericOuter2View(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericOuter2View<Storage> &operator=(
+      const GenericOuter2View<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_outer().Known()) return false;
+    if (has_outer().ValueOrDefault() && !outer().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericOuter2View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_outer().Known()) return false;
+    if (!emboss_reserved_local_other.has_outer().Known()) return false;
+
+    if (emboss_reserved_local_other.has_outer().ValueOrDefault() &&
+        !has_outer().ValueOrDefault())
+      return false;
+    if (has_outer().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_outer().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_outer().ValueOrDefault() &&
+        has_outer().ValueOrDefault() &&
+        !outer().Equals(emboss_reserved_local_other.outer()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericOuter2View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_outer().ValueOr(false) &&
+        !has_outer().ValueOr(false))
+      return false;
+    if (has_outer().ValueOr(false) &&
+        !emboss_reserved_local_other.has_outer().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_outer().ValueOr(false) &&
+        has_outer().ValueOr(false) &&
+        !outer().UncheckedEquals(emboss_reserved_local_other.outer()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericOuter2View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericOuter2View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericOuter2View<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "outer") {
+        if (!outer().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_outer().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          outer().IsAggregate() || outer().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("outer: ");
+        outer().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !outer().IsAggregate() && !outer().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# outer: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::test::GenericOuterView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ outer() const;
+  ::emboss::support::Maybe<bool> has_outer() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericOuter2View;
+};
+using Outer2View =
+    GenericOuter2View</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using Outer2Writer =
+    GenericOuter2View</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericOuter2View {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericOuter2View<
+    GenericOuter2View<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericOuter2View<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeOuter2View( T &&emboss_reserved_local_arg) {
+  return GenericOuter2View<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericOuter2View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeOuter2View( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericOuter2View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericOuter2View<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedOuter2View(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericOuter2View<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace Outer2 {
+
+}  // namespace Outer2
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericOuterView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericOuter2View<Storage>::outer()
+    const {
+
+  if ( has_outer().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(16LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericOuterView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericOuterView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericOuter2View<Storage>::has_outer() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Outer2 {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(16LL)).ValueOrDefault();
+}
+}  // namespace Outer2
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOuter2View<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Outer2::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOuter2View<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Outer2::IntrinsicSizeInBytes();
+}
+
+namespace Outer2 {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(16LL)).ValueOrDefault();
+}
+}  // namespace Outer2
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOuter2View<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Outer2::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOuter2View<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Outer2::MaxSizeInBytes();
+}
+
+namespace Outer2 {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(16LL)).ValueOrDefault();
+}
+}  // namespace Outer2
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOuter2View<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Outer2::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOuter2View<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Outer2::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_IMPORTER2_EMB_H_
+
diff --git a/testdata/golden_cpp/inline_type.emb.h b/testdata/golden_cpp/inline_type.emb.h
new file mode 100644
index 0000000..8f89827
--- /dev/null
+++ b/testdata/golden_cpp/inline_type.emb.h
@@ -0,0 +1,885 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_INLINE_TYPE_EMB_H_
+#define TESTDATA_INLINE_TYPE_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace Foo {
+enum class Status : ::std::uint64_t;
+
+
+enum class SecondaryStatus : ::std::uint64_t;
+
+
+}  // namespace Foo
+
+
+template <class Storage>
+class GenericFooView;
+
+
+
+
+
+
+namespace Foo {
+enum class Status : ::std::uint64_t {
+  OK = static_cast</**/::std::int32_t>(0LL),
+  FAILURE = static_cast</**/::std::int32_t>(12LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<Status> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   Status *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("OK", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Status::OK;
+      return true;
+    }
+
+    if (!strcmp("FAILURE", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Status::FAILURE;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      Status emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Status::OK: return "OK";
+
+      case Status::FAILURE: return "FAILURE";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(Status emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Status::OK: return true;
+
+      case Status::FAILURE: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       Status emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<Status>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    Status *emboss_reserved_local_result) {
+  return EnumTraits<Status>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    Status emboss_reserved_local_value) {
+  return EnumTraits<Status>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(Status emboss_reserved_local_value) {
+  return EnumTraits<Status>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    Status emboss_reserved_local_value) {
+  return EnumTraits<Status>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+
+enum class SecondaryStatus : ::std::uint64_t {
+  OK = static_cast</**/::std::int32_t>(12LL),
+  FAILURE = static_cast</**/::std::int32_t>(0LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<SecondaryStatus> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   SecondaryStatus *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("OK", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = SecondaryStatus::OK;
+      return true;
+    }
+
+    if (!strcmp("FAILURE", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = SecondaryStatus::FAILURE;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      SecondaryStatus emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case SecondaryStatus::OK: return "OK";
+
+      case SecondaryStatus::FAILURE: return "FAILURE";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(SecondaryStatus emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case SecondaryStatus::OK: return true;
+
+      case SecondaryStatus::FAILURE: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       SecondaryStatus emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<SecondaryStatus>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    SecondaryStatus *emboss_reserved_local_result) {
+  return EnumTraits<SecondaryStatus>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    SecondaryStatus emboss_reserved_local_value) {
+  return EnumTraits<SecondaryStatus>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(SecondaryStatus emboss_reserved_local_value) {
+  return EnumTraits<SecondaryStatus>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    SecondaryStatus emboss_reserved_local_value) {
+  return EnumTraits<SecondaryStatus>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+
+}  // namespace Foo
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericFooView;
+
+template <class Storage>
+class GenericFooView final {
+ public:
+  GenericFooView() : backing_() {}
+  explicit GenericFooView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericFooView(
+      const GenericFooView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericFooView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericFooView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericFooView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericFooView<Storage> &operator=(
+      const GenericFooView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+    using Status = ::emboss::test::Foo::Status;
+  using SecondaryStatus = ::emboss::test::Foo::SecondaryStatus;
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_status().Known()) return false;
+    if (has_status().ValueOrDefault() && !status().Ok()) return false;
+
+
+    if (!has_secondary_status().Known()) return false;
+    if (has_secondary_status().ValueOrDefault() && !secondary_status().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericFooView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_status().Known()) return false;
+    if (!emboss_reserved_local_other.has_status().Known()) return false;
+
+    if (emboss_reserved_local_other.has_status().ValueOrDefault() &&
+        !has_status().ValueOrDefault())
+      return false;
+    if (has_status().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_status().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_status().ValueOrDefault() &&
+        has_status().ValueOrDefault() &&
+        !status().Equals(emboss_reserved_local_other.status()))
+      return false;
+
+
+
+    if (!has_secondary_status().Known()) return false;
+    if (!emboss_reserved_local_other.has_secondary_status().Known()) return false;
+
+    if (emboss_reserved_local_other.has_secondary_status().ValueOrDefault() &&
+        !has_secondary_status().ValueOrDefault())
+      return false;
+    if (has_secondary_status().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_secondary_status().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_secondary_status().ValueOrDefault() &&
+        has_secondary_status().ValueOrDefault() &&
+        !secondary_status().Equals(emboss_reserved_local_other.secondary_status()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericFooView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_status().ValueOr(false) &&
+        !has_status().ValueOr(false))
+      return false;
+    if (has_status().ValueOr(false) &&
+        !emboss_reserved_local_other.has_status().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_status().ValueOr(false) &&
+        has_status().ValueOr(false) &&
+        !status().UncheckedEquals(emboss_reserved_local_other.status()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_secondary_status().ValueOr(false) &&
+        !has_secondary_status().ValueOr(false))
+      return false;
+    if (has_secondary_status().ValueOr(false) &&
+        !emboss_reserved_local_other.has_secondary_status().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_secondary_status().ValueOr(false) &&
+        has_secondary_status().ValueOr(false) &&
+        !secondary_status().UncheckedEquals(emboss_reserved_local_other.secondary_status()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericFooView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericFooView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericFooView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "status") {
+        if (!status().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "secondary_status") {
+        if (!secondary_status().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_status().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          status().IsAggregate() || status().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("status: ");
+        status().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !status().IsAggregate() && !status().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# status: UNREADABLE\n");
+      }
+    }
+
+    if (has_secondary_status().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          secondary_status().IsAggregate() || secondary_status().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("secondary_status: ");
+        secondary_status().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !secondary_status().IsAggregate() && !secondary_status().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# secondary_status: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Foo::Status,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ status() const;
+  ::emboss::support::Maybe<bool> has_status() const;
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Foo::SecondaryStatus,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ secondary_status() const;
+  ::emboss::support::Maybe<bool> has_secondary_status() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericFooView;
+};
+using FooView =
+    GenericFooView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using FooWriter =
+    GenericFooView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericFooView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericFooView<
+    GenericFooView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericFooView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeFooView( T &&emboss_reserved_local_arg) {
+  return GenericFooView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericFooView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeFooView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericFooView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericFooView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedFooView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericFooView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace Foo {
+
+
+}  // namespace Foo
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Foo::Status,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericFooView<Storage>::status()
+    const {
+
+  if ( has_status().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Foo::Status,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Foo::Status,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericFooView<Storage>::has_status() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Foo::SecondaryStatus,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericFooView<Storage>::secondary_status()
+    const {
+
+  if ( has_secondary_status().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Foo::SecondaryStatus,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Foo::SecondaryStatus,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericFooView<Storage>::has_secondary_status() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Foo {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace Foo
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFooView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Foo::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFooView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Foo::IntrinsicSizeInBytes();
+}
+
+namespace Foo {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace Foo
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFooView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Foo::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFooView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Foo::MaxSizeInBytes();
+}
+
+namespace Foo {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace Foo
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFooView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Foo::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericFooView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Foo::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_INLINE_TYPE_EMB_H_
+
diff --git a/testdata/golden_cpp/int_sizes.emb.h b/testdata/golden_cpp/int_sizes.emb.h
new file mode 100644
index 0000000..fe697e9
--- /dev/null
+++ b/testdata/golden_cpp/int_sizes.emb.h
@@ -0,0 +1,1439 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_INT_SIZES_EMB_H_
+#define TESTDATA_INT_SIZES_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace Sizes {
+
+}  // namespace Sizes
+
+
+template <class Storage>
+class GenericSizesView;
+
+
+
+
+
+
+
+
+
+
+
+
+namespace Sizes {
+
+}  // namespace Sizes
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericSizesView;
+
+template <class Storage>
+class GenericSizesView final {
+ public:
+  GenericSizesView() : backing_() {}
+  explicit GenericSizesView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericSizesView(
+      const GenericSizesView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericSizesView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericSizesView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericSizesView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericSizesView<Storage> &operator=(
+      const GenericSizesView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_one_byte().Known()) return false;
+    if (has_one_byte().ValueOrDefault() && !one_byte().Ok()) return false;
+
+
+    if (!has_two_byte().Known()) return false;
+    if (has_two_byte().ValueOrDefault() && !two_byte().Ok()) return false;
+
+
+    if (!has_three_byte().Known()) return false;
+    if (has_three_byte().ValueOrDefault() && !three_byte().Ok()) return false;
+
+
+    if (!has_four_byte().Known()) return false;
+    if (has_four_byte().ValueOrDefault() && !four_byte().Ok()) return false;
+
+
+    if (!has_five_byte().Known()) return false;
+    if (has_five_byte().ValueOrDefault() && !five_byte().Ok()) return false;
+
+
+    if (!has_six_byte().Known()) return false;
+    if (has_six_byte().ValueOrDefault() && !six_byte().Ok()) return false;
+
+
+    if (!has_seven_byte().Known()) return false;
+    if (has_seven_byte().ValueOrDefault() && !seven_byte().Ok()) return false;
+
+
+    if (!has_eight_byte().Known()) return false;
+    if (has_eight_byte().ValueOrDefault() && !eight_byte().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericSizesView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_one_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_one_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOrDefault() &&
+        !has_one_byte().ValueOrDefault())
+      return false;
+    if (has_one_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_one_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOrDefault() &&
+        has_one_byte().ValueOrDefault() &&
+        !one_byte().Equals(emboss_reserved_local_other.one_byte()))
+      return false;
+
+
+
+    if (!has_two_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_two_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOrDefault() &&
+        !has_two_byte().ValueOrDefault())
+      return false;
+    if (has_two_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_two_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOrDefault() &&
+        has_two_byte().ValueOrDefault() &&
+        !two_byte().Equals(emboss_reserved_local_other.two_byte()))
+      return false;
+
+
+
+    if (!has_three_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_three_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOrDefault() &&
+        !has_three_byte().ValueOrDefault())
+      return false;
+    if (has_three_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_three_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOrDefault() &&
+        has_three_byte().ValueOrDefault() &&
+        !three_byte().Equals(emboss_reserved_local_other.three_byte()))
+      return false;
+
+
+
+    if (!has_four_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_four_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOrDefault() &&
+        !has_four_byte().ValueOrDefault())
+      return false;
+    if (has_four_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_four_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOrDefault() &&
+        has_four_byte().ValueOrDefault() &&
+        !four_byte().Equals(emboss_reserved_local_other.four_byte()))
+      return false;
+
+
+
+    if (!has_five_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_five_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOrDefault() &&
+        !has_five_byte().ValueOrDefault())
+      return false;
+    if (has_five_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_five_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOrDefault() &&
+        has_five_byte().ValueOrDefault() &&
+        !five_byte().Equals(emboss_reserved_local_other.five_byte()))
+      return false;
+
+
+
+    if (!has_six_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_six_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOrDefault() &&
+        !has_six_byte().ValueOrDefault())
+      return false;
+    if (has_six_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_six_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOrDefault() &&
+        has_six_byte().ValueOrDefault() &&
+        !six_byte().Equals(emboss_reserved_local_other.six_byte()))
+      return false;
+
+
+
+    if (!has_seven_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_seven_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOrDefault() &&
+        !has_seven_byte().ValueOrDefault())
+      return false;
+    if (has_seven_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_seven_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOrDefault() &&
+        has_seven_byte().ValueOrDefault() &&
+        !seven_byte().Equals(emboss_reserved_local_other.seven_byte()))
+      return false;
+
+
+
+    if (!has_eight_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_eight_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOrDefault() &&
+        !has_eight_byte().ValueOrDefault())
+      return false;
+    if (has_eight_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_eight_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOrDefault() &&
+        has_eight_byte().ValueOrDefault() &&
+        !eight_byte().Equals(emboss_reserved_local_other.eight_byte()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericSizesView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_one_byte().ValueOr(false) &&
+        !has_one_byte().ValueOr(false))
+      return false;
+    if (has_one_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_one_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOr(false) &&
+        has_one_byte().ValueOr(false) &&
+        !one_byte().UncheckedEquals(emboss_reserved_local_other.one_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOr(false) &&
+        !has_two_byte().ValueOr(false))
+      return false;
+    if (has_two_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_two_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOr(false) &&
+        has_two_byte().ValueOr(false) &&
+        !two_byte().UncheckedEquals(emboss_reserved_local_other.two_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOr(false) &&
+        !has_three_byte().ValueOr(false))
+      return false;
+    if (has_three_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_three_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOr(false) &&
+        has_three_byte().ValueOr(false) &&
+        !three_byte().UncheckedEquals(emboss_reserved_local_other.three_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOr(false) &&
+        !has_four_byte().ValueOr(false))
+      return false;
+    if (has_four_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_four_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOr(false) &&
+        has_four_byte().ValueOr(false) &&
+        !four_byte().UncheckedEquals(emboss_reserved_local_other.four_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOr(false) &&
+        !has_five_byte().ValueOr(false))
+      return false;
+    if (has_five_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_five_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOr(false) &&
+        has_five_byte().ValueOr(false) &&
+        !five_byte().UncheckedEquals(emboss_reserved_local_other.five_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOr(false) &&
+        !has_six_byte().ValueOr(false))
+      return false;
+    if (has_six_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_six_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOr(false) &&
+        has_six_byte().ValueOr(false) &&
+        !six_byte().UncheckedEquals(emboss_reserved_local_other.six_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOr(false) &&
+        !has_seven_byte().ValueOr(false))
+      return false;
+    if (has_seven_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_seven_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOr(false) &&
+        has_seven_byte().ValueOr(false) &&
+        !seven_byte().UncheckedEquals(emboss_reserved_local_other.seven_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOr(false) &&
+        !has_eight_byte().ValueOr(false))
+      return false;
+    if (has_eight_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_eight_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOr(false) &&
+        has_eight_byte().ValueOr(false) &&
+        !eight_byte().UncheckedEquals(emboss_reserved_local_other.eight_byte()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericSizesView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericSizesView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericSizesView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "one_byte") {
+        if (!one_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "two_byte") {
+        if (!two_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "three_byte") {
+        if (!three_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "four_byte") {
+        if (!four_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "five_byte") {
+        if (!five_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "six_byte") {
+        if (!six_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "seven_byte") {
+        if (!seven_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "eight_byte") {
+        if (!eight_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_one_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          one_byte().IsAggregate() || one_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("one_byte: ");
+        one_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !one_byte().IsAggregate() && !one_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# one_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_two_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          two_byte().IsAggregate() || two_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("two_byte: ");
+        two_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !two_byte().IsAggregate() && !two_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# two_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_three_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          three_byte().IsAggregate() || three_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("three_byte: ");
+        three_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !three_byte().IsAggregate() && !three_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# three_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_four_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          four_byte().IsAggregate() || four_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("four_byte: ");
+        four_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !four_byte().IsAggregate() && !four_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# four_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_five_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          five_byte().IsAggregate() || five_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("five_byte: ");
+        five_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !five_byte().IsAggregate() && !five_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# five_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_six_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          six_byte().IsAggregate() || six_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("six_byte: ");
+        six_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !six_byte().IsAggregate() && !six_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# six_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_seven_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          seven_byte().IsAggregate() || seven_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("seven_byte: ");
+        seven_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !seven_byte().IsAggregate() && !seven_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# seven_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_eight_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          eight_byte().IsAggregate() || eight_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("eight_byte: ");
+        eight_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !eight_byte().IsAggregate() && !eight_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# eight_byte: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ one_byte() const;
+  ::emboss::support::Maybe<bool> has_one_byte() const;
+
+ public:
+  typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+ two_byte() const;
+  ::emboss::support::Maybe<bool> has_two_byte() const;
+
+ public:
+  typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+ three_byte() const;
+  ::emboss::support::Maybe<bool> has_three_byte() const;
+
+ public:
+  typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+ four_byte() const;
+  ::emboss::support::Maybe<bool> has_four_byte() const;
+
+ public:
+  typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 40>>
+
+ five_byte() const;
+  ::emboss::support::Maybe<bool> has_five_byte() const;
+
+ public:
+  typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 15>>, 48>>
+
+ six_byte() const;
+  ::emboss::support::Maybe<bool> has_six_byte() const;
+
+ public:
+  typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 56>>
+
+ seven_byte() const;
+  ::emboss::support::Maybe<bool> has_seven_byte() const;
+
+ public:
+  typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 28>>, 64>>
+
+ eight_byte() const;
+  ::emboss::support::Maybe<bool> has_eight_byte() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericSizesView;
+};
+using SizesView =
+    GenericSizesView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using SizesWriter =
+    GenericSizesView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericSizesView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericSizesView<
+    GenericSizesView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericSizesView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeSizesView( T &&emboss_reserved_local_arg) {
+  return GenericSizesView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericSizesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeSizesView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericSizesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericSizesView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedSizesView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericSizesView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace Sizes {
+
+}  // namespace Sizes
+
+
+template <class Storage>
+inline typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericSizesView<Storage>::one_byte()
+    const {
+
+  if ( has_one_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizesView<Storage>::has_one_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+ GenericSizesView<Storage>::two_byte()
+    const {
+
+  if ( has_two_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizesView<Storage>::has_two_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+ GenericSizesView<Storage>::three_byte()
+    const {
+
+  if ( has_three_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   3>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizesView<Storage>::has_three_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+ GenericSizesView<Storage>::four_byte()
+    const {
+
+  if ( has_four_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   6>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizesView<Storage>::has_four_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 40>>
+
+ GenericSizesView<Storage>::five_byte()
+    const {
+
+  if ( has_five_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 40>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   10>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 40>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizesView<Storage>::has_five_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 15>>, 48>>
+
+ GenericSizesView<Storage>::six_byte()
+    const {
+
+  if ( has_six_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(15LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 15>>, 48>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   15>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 15>>, 48>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizesView<Storage>::has_six_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 56>>
+
+ GenericSizesView<Storage>::seven_byte()
+    const {
+
+  if ( has_seven_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(7LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(21LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 56>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   21>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 56>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizesView<Storage>::has_seven_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 28>>, 64>>
+
+ GenericSizesView<Storage>::eight_byte()
+    const {
+
+  if ( has_eight_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(28LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 28>>, 64>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   28>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 28>>, 64>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizesView<Storage>::has_eight_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Sizes {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(36LL)).ValueOrDefault();
+}
+}  // namespace Sizes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizesView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Sizes::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizesView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Sizes::IntrinsicSizeInBytes();
+}
+
+namespace Sizes {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(36LL)).ValueOrDefault();
+}
+}  // namespace Sizes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizesView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Sizes::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizesView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Sizes::MaxSizeInBytes();
+}
+
+namespace Sizes {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(36LL)).ValueOrDefault();
+}
+}  // namespace Sizes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizesView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Sizes::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizesView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Sizes::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_INT_SIZES_EMB_H_
+
diff --git a/testdata/golden_cpp/large_array.emb.h b/testdata/golden_cpp/large_array.emb.h
new file mode 100644
index 0000000..47b4511
--- /dev/null
+++ b/testdata/golden_cpp/large_array.emb.h
@@ -0,0 +1,741 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_LARGE_ARRAY_EMB_H_
+#define TESTDATA_LARGE_ARRAY_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace UIntArray {
+
+}  // namespace UIntArray
+
+
+template <class Storage>
+class GenericUIntArrayView;
+
+
+
+
+
+
+namespace UIntArray {
+
+}  // namespace UIntArray
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericUIntArrayView;
+
+template <class Storage>
+class GenericUIntArrayView final {
+ public:
+  GenericUIntArrayView() : backing_() {}
+  explicit GenericUIntArrayView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericUIntArrayView(
+      const GenericUIntArrayView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericUIntArrayView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericUIntArrayView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericUIntArrayView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericUIntArrayView<Storage> &operator=(
+      const GenericUIntArrayView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_element_count().Known()) return false;
+    if (has_element_count().ValueOrDefault() && !element_count().Ok()) return false;
+
+
+    if (!has_elements().Known()) return false;
+    if (has_elements().ValueOrDefault() && !elements().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericUIntArrayView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_element_count().Known()) return false;
+    if (!emboss_reserved_local_other.has_element_count().Known()) return false;
+
+    if (emboss_reserved_local_other.has_element_count().ValueOrDefault() &&
+        !has_element_count().ValueOrDefault())
+      return false;
+    if (has_element_count().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_element_count().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_element_count().ValueOrDefault() &&
+        has_element_count().ValueOrDefault() &&
+        !element_count().Equals(emboss_reserved_local_other.element_count()))
+      return false;
+
+
+
+    if (!has_elements().Known()) return false;
+    if (!emboss_reserved_local_other.has_elements().Known()) return false;
+
+    if (emboss_reserved_local_other.has_elements().ValueOrDefault() &&
+        !has_elements().ValueOrDefault())
+      return false;
+    if (has_elements().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_elements().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_elements().ValueOrDefault() &&
+        has_elements().ValueOrDefault() &&
+        !elements().Equals(emboss_reserved_local_other.elements()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericUIntArrayView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_element_count().ValueOr(false) &&
+        !has_element_count().ValueOr(false))
+      return false;
+    if (has_element_count().ValueOr(false) &&
+        !emboss_reserved_local_other.has_element_count().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_element_count().ValueOr(false) &&
+        has_element_count().ValueOr(false) &&
+        !element_count().UncheckedEquals(emboss_reserved_local_other.element_count()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_elements().ValueOr(false) &&
+        !has_elements().ValueOr(false))
+      return false;
+    if (has_elements().ValueOr(false) &&
+        !emboss_reserved_local_other.has_elements().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_elements().ValueOr(false) &&
+        has_elements().ValueOr(false) &&
+        !elements().UncheckedEquals(emboss_reserved_local_other.elements()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericUIntArrayView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericUIntArrayView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericUIntArrayView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "element_count") {
+        if (!element_count().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "elements") {
+        if (!elements().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_element_count().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          element_count().IsAggregate() || element_count().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("element_count: ");
+        element_count().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !element_count().IsAggregate() && !element_count().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# element_count: UNREADABLE\n");
+      }
+    }
+
+    if (has_elements().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          elements().IsAggregate() || elements().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("elements: ");
+        elements().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !elements().IsAggregate() && !elements().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# elements: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ element_count() const;
+  ::emboss::support::Maybe<bool> has_element_count() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>::template OffsetStorageType</**/4, 0>>, 32>>
+
+, typename Storage::template OffsetStorageType</**/0, 4>, 4,
+    8 >
+
+ elements() const;
+  ::emboss::support::Maybe<bool> has_elements() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int64_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericUIntArrayView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int64_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int64_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int64_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.element_count();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::uint32_t>(static_cast</**/::std::uint32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::uint32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Product</**/::std::int64_t, ::std::int64_t, ::std::int32_t, ::std::uint32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)), emboss_reserved_local_subexpr_2);
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Sum</**/::std::int64_t, ::std::int64_t, ::std::int32_t, ::std::int64_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)), emboss_reserved_local_subexpr_3);
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Choice</**/::std::int64_t, ::std::int64_t, bool, ::std::int64_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_4, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Maximum</**/::std::int64_t, ::std::int64_t, ::std::int32_t, ::std::int32_t, ::std::int64_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)), emboss_reserved_local_subexpr_5);
+
+      return emboss_reserved_local_subexpr_6;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int64_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericUIntArrayView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int64_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int64_t Read();
+    static constexpr ::std::int64_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericUIntArrayView;
+};
+using UIntArrayView =
+    GenericUIntArrayView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using UIntArrayWriter =
+    GenericUIntArrayView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericUIntArrayView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericUIntArrayView<
+    GenericUIntArrayView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericUIntArrayView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeUIntArrayView( T &&emboss_reserved_local_arg) {
+  return GenericUIntArrayView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericUIntArrayView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeUIntArrayView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericUIntArrayView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericUIntArrayView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedUIntArrayView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericUIntArrayView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace UIntArray {
+
+}  // namespace UIntArray
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ GenericUIntArrayView<Storage>::element_count()
+    const {
+
+  if ( has_element_count().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericUIntArrayView<Storage>::has_element_count() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>::template OffsetStorageType</**/4, 0>>, 32>>
+
+, typename Storage::template OffsetStorageType</**/0, 4>, 4,
+    8 >
+
+ GenericUIntArrayView<Storage>::elements()
+    const {
+
+  if ( has_elements().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = element_count();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::uint32_t>(static_cast</**/::std::uint32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::uint32_t>());
+    const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Product</**/::std::int64_t, ::std::int64_t, ::std::int32_t, ::std::uint32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)), emboss_reserved_local_subexpr_2);
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_3;
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>::template OffsetStorageType</**/4, 0>>, 32>>
+
+, typename Storage::template OffsetStorageType</**/0, 4>, 4,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   4>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>::template OffsetStorageType</**/4, 0>>, 32>>
+
+, typename Storage::template OffsetStorageType</**/0, 4>, 4,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericUIntArrayView<Storage>::has_elements() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericUIntArrayView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericUIntArrayView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericUIntArrayView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericUIntArrayView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace UIntArray {
+inline constexpr ::std::int64_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int64_t>(static_cast</**/::std::int64_t>(17179869184LL)).ValueOrDefault();
+}
+}  // namespace UIntArray
+
+template <class Storage>
+inline constexpr ::std::int64_t
+GenericUIntArrayView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return UIntArray::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int64_t
+GenericUIntArrayView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return UIntArray::MaxSizeInBytes();
+}
+
+namespace UIntArray {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace UIntArray
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericUIntArrayView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return UIntArray::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericUIntArrayView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return UIntArray::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_LARGE_ARRAY_EMB_H_
+
diff --git a/testdata/golden_cpp/nested_structure.emb.h b/testdata/golden_cpp/nested_structure.emb.h
new file mode 100644
index 0000000..b953e31
--- /dev/null
+++ b/testdata/golden_cpp/nested_structure.emb.h
@@ -0,0 +1,2117 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_NESTED_STRUCTURE_EMB_H_
+#define TESTDATA_NESTED_STRUCTURE_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace Container {
+
+}  // namespace Container
+
+
+template <class Storage>
+class GenericContainerView;
+
+namespace Box {
+
+}  // namespace Box
+
+
+template <class Storage>
+class GenericBoxView;
+
+namespace Truck {
+
+}  // namespace Truck
+
+
+template <class Storage>
+class GenericTruckView;
+
+
+
+
+
+
+
+namespace Container {
+
+}  // namespace Container
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericContainerView;
+
+template <class Storage>
+class GenericContainerView final {
+ public:
+  GenericContainerView() : backing_() {}
+  explicit GenericContainerView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericContainerView(
+      const GenericContainerView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericContainerView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericContainerView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericContainerView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericContainerView<Storage> &operator=(
+      const GenericContainerView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_weight().Known()) return false;
+    if (has_weight().ValueOrDefault() && !weight().Ok()) return false;
+
+
+    if (!has_important_box().Known()) return false;
+    if (has_important_box().ValueOrDefault() && !important_box().Ok()) return false;
+
+
+    if (!has_other_box().Known()) return false;
+    if (has_other_box().ValueOrDefault() && !other_box().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericContainerView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_weight().Known()) return false;
+    if (!emboss_reserved_local_other.has_weight().Known()) return false;
+
+    if (emboss_reserved_local_other.has_weight().ValueOrDefault() &&
+        !has_weight().ValueOrDefault())
+      return false;
+    if (has_weight().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_weight().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_weight().ValueOrDefault() &&
+        has_weight().ValueOrDefault() &&
+        !weight().Equals(emboss_reserved_local_other.weight()))
+      return false;
+
+
+
+    if (!has_important_box().Known()) return false;
+    if (!emboss_reserved_local_other.has_important_box().Known()) return false;
+
+    if (emboss_reserved_local_other.has_important_box().ValueOrDefault() &&
+        !has_important_box().ValueOrDefault())
+      return false;
+    if (has_important_box().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_important_box().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_important_box().ValueOrDefault() &&
+        has_important_box().ValueOrDefault() &&
+        !important_box().Equals(emboss_reserved_local_other.important_box()))
+      return false;
+
+
+
+    if (!has_other_box().Known()) return false;
+    if (!emboss_reserved_local_other.has_other_box().Known()) return false;
+
+    if (emboss_reserved_local_other.has_other_box().ValueOrDefault() &&
+        !has_other_box().ValueOrDefault())
+      return false;
+    if (has_other_box().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_other_box().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_other_box().ValueOrDefault() &&
+        has_other_box().ValueOrDefault() &&
+        !other_box().Equals(emboss_reserved_local_other.other_box()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericContainerView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_weight().ValueOr(false) &&
+        !has_weight().ValueOr(false))
+      return false;
+    if (has_weight().ValueOr(false) &&
+        !emboss_reserved_local_other.has_weight().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_weight().ValueOr(false) &&
+        has_weight().ValueOr(false) &&
+        !weight().UncheckedEquals(emboss_reserved_local_other.weight()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_important_box().ValueOr(false) &&
+        !has_important_box().ValueOr(false))
+      return false;
+    if (has_important_box().ValueOr(false) &&
+        !emboss_reserved_local_other.has_important_box().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_important_box().ValueOr(false) &&
+        has_important_box().ValueOr(false) &&
+        !important_box().UncheckedEquals(emboss_reserved_local_other.important_box()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_other_box().ValueOr(false) &&
+        !has_other_box().ValueOr(false))
+      return false;
+    if (has_other_box().ValueOr(false) &&
+        !emboss_reserved_local_other.has_other_box().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_other_box().ValueOr(false) &&
+        has_other_box().ValueOr(false) &&
+        !other_box().UncheckedEquals(emboss_reserved_local_other.other_box()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericContainerView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericContainerView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericContainerView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "weight") {
+        if (!weight().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "important_box") {
+        if (!important_box().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "other_box") {
+        if (!other_box().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_weight().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          weight().IsAggregate() || weight().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("weight: ");
+        weight().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !weight().IsAggregate() && !weight().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# weight: UNREADABLE\n");
+      }
+    }
+
+    if (has_important_box().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          important_box().IsAggregate() || important_box().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("important_box: ");
+        important_box().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !important_box().IsAggregate() && !important_box().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# important_box: UNREADABLE\n");
+      }
+    }
+
+    if (has_other_box().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          other_box().IsAggregate() || other_box().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("other_box: ");
+        other_box().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !other_box().IsAggregate() && !other_box().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# other_box: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ weight() const;
+  ::emboss::support::Maybe<bool> has_weight() const;
+
+ public:
+  typename ::emboss::test::GenericBoxView<typename Storage::template OffsetStorageType</**/0, 4>>
+
+ important_box() const;
+  ::emboss::support::Maybe<bool> has_important_box() const;
+
+ public:
+  typename ::emboss::test::GenericBoxView<typename Storage::template OffsetStorageType</**/0, 12>>
+
+ other_box() const;
+  ::emboss::support::Maybe<bool> has_other_box() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericContainerView;
+};
+using ContainerView =
+    GenericContainerView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ContainerWriter =
+    GenericContainerView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericContainerView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericContainerView<
+    GenericContainerView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericContainerView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeContainerView( T &&emboss_reserved_local_arg) {
+  return GenericContainerView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericContainerView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeContainerView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericContainerView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericContainerView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedContainerView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericContainerView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace Box {
+
+}  // namespace Box
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericBoxView;
+
+template <class Storage>
+class GenericBoxView final {
+ public:
+  GenericBoxView() : backing_() {}
+  explicit GenericBoxView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericBoxView(
+      const GenericBoxView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericBoxView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericBoxView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericBoxView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericBoxView<Storage> &operator=(
+      const GenericBoxView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_id().Known()) return false;
+    if (has_id().ValueOrDefault() && !id().Ok()) return false;
+
+
+    if (!has_count().Known()) return false;
+    if (has_count().ValueOrDefault() && !count().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericBoxView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_id().Known()) return false;
+    if (!emboss_reserved_local_other.has_id().Known()) return false;
+
+    if (emboss_reserved_local_other.has_id().ValueOrDefault() &&
+        !has_id().ValueOrDefault())
+      return false;
+    if (has_id().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_id().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_id().ValueOrDefault() &&
+        has_id().ValueOrDefault() &&
+        !id().Equals(emboss_reserved_local_other.id()))
+      return false;
+
+
+
+    if (!has_count().Known()) return false;
+    if (!emboss_reserved_local_other.has_count().Known()) return false;
+
+    if (emboss_reserved_local_other.has_count().ValueOrDefault() &&
+        !has_count().ValueOrDefault())
+      return false;
+    if (has_count().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_count().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_count().ValueOrDefault() &&
+        has_count().ValueOrDefault() &&
+        !count().Equals(emboss_reserved_local_other.count()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericBoxView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_id().ValueOr(false) &&
+        !has_id().ValueOr(false))
+      return false;
+    if (has_id().ValueOr(false) &&
+        !emboss_reserved_local_other.has_id().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_id().ValueOr(false) &&
+        has_id().ValueOr(false) &&
+        !id().UncheckedEquals(emboss_reserved_local_other.id()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_count().ValueOr(false) &&
+        !has_count().ValueOr(false))
+      return false;
+    if (has_count().ValueOr(false) &&
+        !emboss_reserved_local_other.has_count().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_count().ValueOr(false) &&
+        has_count().ValueOr(false) &&
+        !count().UncheckedEquals(emboss_reserved_local_other.count()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericBoxView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericBoxView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericBoxView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "id") {
+        if (!id().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "count") {
+        if (!count().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_id().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          id().IsAggregate() || id().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("id: ");
+        id().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !id().IsAggregate() && !id().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# id: UNREADABLE\n");
+      }
+    }
+
+    if (has_count().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          count().IsAggregate() || count().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("count: ");
+        count().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !count().IsAggregate() && !count().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# count: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ id() const;
+  ::emboss::support::Maybe<bool> has_id() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+ count() const;
+  ::emboss::support::Maybe<bool> has_count() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericBoxView;
+};
+using BoxView =
+    GenericBoxView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using BoxWriter =
+    GenericBoxView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericBoxView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericBoxView<
+    GenericBoxView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericBoxView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeBoxView( T &&emboss_reserved_local_arg) {
+  return GenericBoxView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericBoxView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeBoxView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericBoxView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericBoxView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedBoxView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericBoxView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace Truck {
+
+}  // namespace Truck
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericTruckView;
+
+template <class Storage>
+class GenericTruckView final {
+ public:
+  GenericTruckView() : backing_() {}
+  explicit GenericTruckView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericTruckView(
+      const GenericTruckView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericTruckView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericTruckView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericTruckView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericTruckView<Storage> &operator=(
+      const GenericTruckView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_id().Known()) return false;
+    if (has_id().ValueOrDefault() && !id().Ok()) return false;
+
+
+    if (!has_cargo().Known()) return false;
+    if (has_cargo().ValueOrDefault() && !cargo().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericTruckView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_id().Known()) return false;
+    if (!emboss_reserved_local_other.has_id().Known()) return false;
+
+    if (emboss_reserved_local_other.has_id().ValueOrDefault() &&
+        !has_id().ValueOrDefault())
+      return false;
+    if (has_id().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_id().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_id().ValueOrDefault() &&
+        has_id().ValueOrDefault() &&
+        !id().Equals(emboss_reserved_local_other.id()))
+      return false;
+
+
+
+    if (!has_cargo().Known()) return false;
+    if (!emboss_reserved_local_other.has_cargo().Known()) return false;
+
+    if (emboss_reserved_local_other.has_cargo().ValueOrDefault() &&
+        !has_cargo().ValueOrDefault())
+      return false;
+    if (has_cargo().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_cargo().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_cargo().ValueOrDefault() &&
+        has_cargo().ValueOrDefault() &&
+        !cargo().Equals(emboss_reserved_local_other.cargo()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericTruckView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_id().ValueOr(false) &&
+        !has_id().ValueOr(false))
+      return false;
+    if (has_id().ValueOr(false) &&
+        !emboss_reserved_local_other.has_id().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_id().ValueOr(false) &&
+        has_id().ValueOr(false) &&
+        !id().UncheckedEquals(emboss_reserved_local_other.id()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_cargo().ValueOr(false) &&
+        !has_cargo().ValueOr(false))
+      return false;
+    if (has_cargo().ValueOr(false) &&
+        !emboss_reserved_local_other.has_cargo().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_cargo().ValueOr(false) &&
+        has_cargo().ValueOr(false) &&
+        !cargo().UncheckedEquals(emboss_reserved_local_other.cargo()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericTruckView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericTruckView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericTruckView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "id") {
+        if (!id().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "cargo") {
+        if (!cargo().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_id().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          id().IsAggregate() || id().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("id: ");
+        id().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !id().IsAggregate() && !id().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# id: UNREADABLE\n");
+      }
+    }
+
+    if (has_cargo().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          cargo().IsAggregate() || cargo().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("cargo: ");
+        cargo().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !cargo().IsAggregate() && !cargo().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# cargo: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ id() const;
+  ::emboss::support::Maybe<bool> has_id() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericContainerView<typename Storage::template OffsetStorageType</**/0, 4>::template OffsetStorageType</**/20, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 4>, 20,
+    8 >
+
+ cargo() const;
+  ::emboss::support::Maybe<bool> has_cargo() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericTruckView;
+};
+using TruckView =
+    GenericTruckView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using TruckWriter =
+    GenericTruckView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericTruckView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericTruckView<
+    GenericTruckView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericTruckView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeTruckView( T &&emboss_reserved_local_arg) {
+  return GenericTruckView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericTruckView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeTruckView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericTruckView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericTruckView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedTruckView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericTruckView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace Container {
+
+}  // namespace Container
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ GenericContainerView<Storage>::weight()
+    const {
+
+  if ( has_weight().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericContainerView<Storage>::has_weight() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericBoxView<typename Storage::template OffsetStorageType</**/0, 4>>
+
+ GenericContainerView<Storage>::important_box()
+    const {
+
+  if ( has_important_box().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericBoxView<typename Storage::template OffsetStorageType</**/0, 4>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   4>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericBoxView<typename Storage::template OffsetStorageType</**/0, 4>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericContainerView<Storage>::has_important_box() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericBoxView<typename Storage::template OffsetStorageType</**/0, 12>>
+
+ GenericContainerView<Storage>::other_box()
+    const {
+
+  if ( has_other_box().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(12LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericBoxView<typename Storage::template OffsetStorageType</**/0, 12>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   12>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericBoxView<typename Storage::template OffsetStorageType</**/0, 12>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericContainerView<Storage>::has_other_box() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Container {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(20LL)).ValueOrDefault();
+}
+}  // namespace Container
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericContainerView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Container::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericContainerView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Container::IntrinsicSizeInBytes();
+}
+
+namespace Container {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(20LL)).ValueOrDefault();
+}
+}  // namespace Container
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericContainerView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Container::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericContainerView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Container::MaxSizeInBytes();
+}
+
+namespace Container {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(20LL)).ValueOrDefault();
+}
+}  // namespace Container
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericContainerView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Container::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericContainerView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Container::MinSizeInBytes();
+}
+namespace Box {
+
+}  // namespace Box
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ GenericBoxView<Storage>::id()
+    const {
+
+  if ( has_id().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBoxView<Storage>::has_id() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+ GenericBoxView<Storage>::count()
+    const {
+
+  if ( has_count().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   4>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBoxView<Storage>::has_count() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Box {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace Box
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBoxView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Box::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBoxView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Box::IntrinsicSizeInBytes();
+}
+
+namespace Box {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace Box
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBoxView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Box::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBoxView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Box::MaxSizeInBytes();
+}
+
+namespace Box {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace Box
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBoxView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Box::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBoxView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Box::MinSizeInBytes();
+}
+namespace Truck {
+
+}  // namespace Truck
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ GenericTruckView<Storage>::id()
+    const {
+
+  if ( has_id().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericTruckView<Storage>::has_id() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericContainerView<typename Storage::template OffsetStorageType</**/0, 4>::template OffsetStorageType</**/20, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 4>, 20,
+    8 >
+
+ GenericTruckView<Storage>::cargo()
+    const {
+
+  if ( has_cargo().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(40LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericContainerView<typename Storage::template OffsetStorageType</**/0, 4>::template OffsetStorageType</**/20, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 4>, 20,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   4>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericContainerView<typename Storage::template OffsetStorageType</**/0, 4>::template OffsetStorageType</**/20, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 4>, 20,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericTruckView<Storage>::has_cargo() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Truck {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(44LL)).ValueOrDefault();
+}
+}  // namespace Truck
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericTruckView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Truck::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericTruckView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Truck::IntrinsicSizeInBytes();
+}
+
+namespace Truck {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(44LL)).ValueOrDefault();
+}
+}  // namespace Truck
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericTruckView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Truck::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericTruckView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Truck::MaxSizeInBytes();
+}
+
+namespace Truck {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(44LL)).ValueOrDefault();
+}
+}  // namespace Truck
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericTruckView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Truck::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericTruckView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Truck::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_NESTED_STRUCTURE_EMB_H_
+
diff --git a/testdata/golden_cpp/next_keyword.emb.h b/testdata/golden_cpp/next_keyword.emb.h
new file mode 100644
index 0000000..624c954
--- /dev/null
+++ b/testdata/golden_cpp/next_keyword.emb.h
@@ -0,0 +1,943 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_NEXT_KEYWORD_EMB_H_
+#define TESTDATA_NEXT_KEYWORD_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace NextKeyword {
+
+}  // namespace NextKeyword
+
+
+template <class Storage>
+class GenericNextKeywordView;
+
+
+
+
+
+
+
+
+namespace NextKeyword {
+
+}  // namespace NextKeyword
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericNextKeywordView;
+
+template <class Storage>
+class GenericNextKeywordView final {
+ public:
+  GenericNextKeywordView() : backing_() {}
+  explicit GenericNextKeywordView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericNextKeywordView(
+      const GenericNextKeywordView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericNextKeywordView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericNextKeywordView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericNextKeywordView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericNextKeywordView<Storage> &operator=(
+      const GenericNextKeywordView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_value32().Known()) return false;
+    if (has_value32().ValueOrDefault() && !value32().Ok()) return false;
+
+
+    if (!has_value16().Known()) return false;
+    if (has_value16().ValueOrDefault() && !value16().Ok()) return false;
+
+
+    if (!has_value8().Known()) return false;
+    if (has_value8().ValueOrDefault() && !value8().Ok()) return false;
+
+
+    if (!has_value8_offset().Known()) return false;
+    if (has_value8_offset().ValueOrDefault() && !value8_offset().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericNextKeywordView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_value32().Known()) return false;
+    if (!emboss_reserved_local_other.has_value32().Known()) return false;
+
+    if (emboss_reserved_local_other.has_value32().ValueOrDefault() &&
+        !has_value32().ValueOrDefault())
+      return false;
+    if (has_value32().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_value32().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_value32().ValueOrDefault() &&
+        has_value32().ValueOrDefault() &&
+        !value32().Equals(emboss_reserved_local_other.value32()))
+      return false;
+
+
+
+    if (!has_value16().Known()) return false;
+    if (!emboss_reserved_local_other.has_value16().Known()) return false;
+
+    if (emboss_reserved_local_other.has_value16().ValueOrDefault() &&
+        !has_value16().ValueOrDefault())
+      return false;
+    if (has_value16().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_value16().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_value16().ValueOrDefault() &&
+        has_value16().ValueOrDefault() &&
+        !value16().Equals(emboss_reserved_local_other.value16()))
+      return false;
+
+
+
+    if (!has_value8().Known()) return false;
+    if (!emboss_reserved_local_other.has_value8().Known()) return false;
+
+    if (emboss_reserved_local_other.has_value8().ValueOrDefault() &&
+        !has_value8().ValueOrDefault())
+      return false;
+    if (has_value8().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_value8().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_value8().ValueOrDefault() &&
+        has_value8().ValueOrDefault() &&
+        !value8().Equals(emboss_reserved_local_other.value8()))
+      return false;
+
+
+
+    if (!has_value8_offset().Known()) return false;
+    if (!emboss_reserved_local_other.has_value8_offset().Known()) return false;
+
+    if (emboss_reserved_local_other.has_value8_offset().ValueOrDefault() &&
+        !has_value8_offset().ValueOrDefault())
+      return false;
+    if (has_value8_offset().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_value8_offset().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_value8_offset().ValueOrDefault() &&
+        has_value8_offset().ValueOrDefault() &&
+        !value8_offset().Equals(emboss_reserved_local_other.value8_offset()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericNextKeywordView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_value32().ValueOr(false) &&
+        !has_value32().ValueOr(false))
+      return false;
+    if (has_value32().ValueOr(false) &&
+        !emboss_reserved_local_other.has_value32().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_value32().ValueOr(false) &&
+        has_value32().ValueOr(false) &&
+        !value32().UncheckedEquals(emboss_reserved_local_other.value32()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_value16().ValueOr(false) &&
+        !has_value16().ValueOr(false))
+      return false;
+    if (has_value16().ValueOr(false) &&
+        !emboss_reserved_local_other.has_value16().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_value16().ValueOr(false) &&
+        has_value16().ValueOr(false) &&
+        !value16().UncheckedEquals(emboss_reserved_local_other.value16()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_value8().ValueOr(false) &&
+        !has_value8().ValueOr(false))
+      return false;
+    if (has_value8().ValueOr(false) &&
+        !emboss_reserved_local_other.has_value8().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_value8().ValueOr(false) &&
+        has_value8().ValueOr(false) &&
+        !value8().UncheckedEquals(emboss_reserved_local_other.value8()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_value8_offset().ValueOr(false) &&
+        !has_value8_offset().ValueOr(false))
+      return false;
+    if (has_value8_offset().ValueOr(false) &&
+        !emboss_reserved_local_other.has_value8_offset().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_value8_offset().ValueOr(false) &&
+        has_value8_offset().ValueOr(false) &&
+        !value8_offset().UncheckedEquals(emboss_reserved_local_other.value8_offset()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericNextKeywordView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericNextKeywordView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericNextKeywordView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "value32") {
+        if (!value32().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "value16") {
+        if (!value16().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "value8") {
+        if (!value8().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "value8_offset") {
+        if (!value8_offset().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_value32().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          value32().IsAggregate() || value32().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("value32: ");
+        value32().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !value32().IsAggregate() && !value32().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# value32: UNREADABLE\n");
+      }
+    }
+
+    if (has_value16().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          value16().IsAggregate() || value16().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("value16: ");
+        value16().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !value16().IsAggregate() && !value16().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# value16: UNREADABLE\n");
+      }
+    }
+
+    if (has_value8().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          value8().IsAggregate() || value8().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("value8: ");
+        value8().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !value8().IsAggregate() && !value8().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# value8: UNREADABLE\n");
+      }
+    }
+
+    if (has_value8_offset().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          value8_offset().IsAggregate() || value8_offset().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("value8_offset: ");
+        value8_offset().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !value8_offset().IsAggregate() && !value8_offset().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# value8_offset: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ value32() const;
+  ::emboss::support::Maybe<bool> has_value32() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 16>>
+
+ value16() const;
+  ::emboss::support::Maybe<bool> has_value16() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 8>>
+
+ value8() const;
+  ::emboss::support::Maybe<bool> has_value8() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 8>>
+
+ value8_offset() const;
+  ::emboss::support::Maybe<bool> has_value8_offset() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericNextKeywordView;
+};
+using NextKeywordView =
+    GenericNextKeywordView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using NextKeywordWriter =
+    GenericNextKeywordView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericNextKeywordView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericNextKeywordView<
+    GenericNextKeywordView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericNextKeywordView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeNextKeywordView( T &&emboss_reserved_local_arg) {
+  return GenericNextKeywordView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericNextKeywordView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeNextKeywordView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericNextKeywordView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericNextKeywordView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedNextKeywordView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericNextKeywordView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace NextKeyword {
+
+}  // namespace NextKeyword
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ GenericNextKeywordView<Storage>::value32()
+    const {
+
+  if ( has_value32().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNextKeywordView<Storage>::has_value32() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 16>>
+
+ GenericNextKeywordView<Storage>::value16()
+    const {
+
+  if ( has_value16().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 16>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   4>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 16>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNextKeywordView<Storage>::has_value16() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 8>>
+
+ GenericNextKeywordView<Storage>::value8()
+    const {
+
+  if ( has_value8().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   6>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNextKeywordView<Storage>::has_value8() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 8>>
+
+ GenericNextKeywordView<Storage>::value8_offset()
+    const {
+
+  if ( has_value8_offset().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   10>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericNextKeywordView<Storage>::has_value8_offset() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace NextKeyword {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(11LL)).ValueOrDefault();
+}
+}  // namespace NextKeyword
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericNextKeywordView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return NextKeyword::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericNextKeywordView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return NextKeyword::IntrinsicSizeInBytes();
+}
+
+namespace NextKeyword {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(11LL)).ValueOrDefault();
+}
+}  // namespace NextKeyword
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericNextKeywordView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return NextKeyword::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericNextKeywordView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return NextKeyword::MaxSizeInBytes();
+}
+
+namespace NextKeyword {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(11LL)).ValueOrDefault();
+}
+}  // namespace NextKeyword
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericNextKeywordView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return NextKeyword::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericNextKeywordView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return NextKeyword::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_NEXT_KEYWORD_EMB_H_
+
diff --git a/testdata/golden_cpp/no_cpp_namespace.emb.h b/testdata/golden_cpp/no_cpp_namespace.emb.h
new file mode 100644
index 0000000..7691741
--- /dev/null
+++ b/testdata/golden_cpp/no_cpp_namespace.emb.h
@@ -0,0 +1,116 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_NO_CPP_NAMESPACE_EMB_H_
+#define TESTDATA_NO_CPP_NAMESPACE_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss_generated_code {
+enum class Foo : ::std::uint64_t;
+
+
+enum class Foo : ::std::uint64_t {
+  VALUE = static_cast</**/::std::int32_t>(10LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<Foo> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   Foo *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("VALUE", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Foo::VALUE;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      Foo emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Foo::VALUE: return "VALUE";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(Foo emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Foo::VALUE: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       Foo emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<Foo>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    Foo *emboss_reserved_local_result) {
+  return EnumTraits<Foo>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    Foo emboss_reserved_local_value) {
+  return EnumTraits<Foo>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(Foo emboss_reserved_local_value) {
+  return EnumTraits<Foo>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    Foo emboss_reserved_local_value) {
+  return EnumTraits<Foo>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+
+
+
+
+}  // namespace emboss_generated_code
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_NO_CPP_NAMESPACE_EMB_H_
+
diff --git a/testdata/golden_cpp/no_enum_traits.emb.h b/testdata/golden_cpp/no_enum_traits.emb.h
new file mode 100644
index 0000000..5f97e05
--- /dev/null
+++ b/testdata/golden_cpp/no_enum_traits.emb.h
@@ -0,0 +1,654 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_NO_ENUM_TRAITS_EMB_H_
+#define TESTDATA_NO_ENUM_TRAITS_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+enum class Foo : ::std::uint64_t;
+
+namespace Bar {
+
+}  // namespace Bar
+
+
+template <class Storage>
+class GenericBarView;
+
+
+enum class Foo : ::std::uint64_t {
+  VALUE = static_cast</**/::std::int32_t>(10LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<Foo> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   Foo *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("VALUE", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Foo::VALUE;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      Foo emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Foo::VALUE: return "VALUE";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(Foo emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Foo::VALUE: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       Foo emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<Foo>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    Foo *emboss_reserved_local_result) {
+  return EnumTraits<Foo>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    Foo emboss_reserved_local_value) {
+  return EnumTraits<Foo>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(Foo emboss_reserved_local_value) {
+  return EnumTraits<Foo>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    Foo emboss_reserved_local_value) {
+  return EnumTraits<Foo>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+
+
+
+namespace Bar {
+
+}  // namespace Bar
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericBarView;
+
+template <class Storage>
+class GenericBarView final {
+ public:
+  GenericBarView() : backing_() {}
+  explicit GenericBarView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericBarView(
+      const GenericBarView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericBarView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericBarView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericBarView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericBarView<Storage> &operator=(
+      const GenericBarView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_foo().Known()) return false;
+    if (has_foo().ValueOrDefault() && !foo().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericBarView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_foo().Known()) return false;
+    if (!emboss_reserved_local_other.has_foo().Known()) return false;
+
+    if (emboss_reserved_local_other.has_foo().ValueOrDefault() &&
+        !has_foo().ValueOrDefault())
+      return false;
+    if (has_foo().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_foo().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_foo().ValueOrDefault() &&
+        has_foo().ValueOrDefault() &&
+        !foo().Equals(emboss_reserved_local_other.foo()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericBarView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_foo().ValueOr(false) &&
+        !has_foo().ValueOr(false))
+      return false;
+    if (has_foo().ValueOr(false) &&
+        !emboss_reserved_local_other.has_foo().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_foo().ValueOr(false) &&
+        has_foo().ValueOr(false) &&
+        !foo().UncheckedEquals(emboss_reserved_local_other.foo()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericBarView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericBarView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericBarView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "foo") {
+        if (!foo().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_foo().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          foo().IsAggregate() || foo().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("foo: ");
+        foo().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !foo().IsAggregate() && !foo().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# foo: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Foo,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ foo() const;
+  ::emboss::support::Maybe<bool> has_foo() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericBarView;
+};
+using BarView =
+    GenericBarView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using BarWriter =
+    GenericBarView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericBarView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericBarView<
+    GenericBarView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericBarView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeBarView( T &&emboss_reserved_local_arg) {
+  return GenericBarView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericBarView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeBarView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericBarView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericBarView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedBarView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericBarView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace Bar {
+
+}  // namespace Bar
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Foo,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericBarView<Storage>::foo()
+    const {
+
+  if ( has_foo().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Foo,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Foo,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBarView<Storage>::has_foo() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Bar {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace Bar
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBarView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Bar::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBarView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Bar::IntrinsicSizeInBytes();
+}
+
+namespace Bar {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace Bar
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBarView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Bar::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBarView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Bar::MaxSizeInBytes();
+}
+
+namespace Bar {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace Bar
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBarView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Bar::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBarView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Bar::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_NO_ENUM_TRAITS_EMB_H_
+
diff --git a/testdata/golden_cpp/parameters.emb.h b/testdata/golden_cpp/parameters.emb.h
new file mode 100644
index 0000000..d60f164
--- /dev/null
+++ b/testdata/golden_cpp/parameters.emb.h
@@ -0,0 +1,10744 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_PARAMETERS_EMB_H_
+#define TESTDATA_PARAMETERS_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+enum class Product : ::std::uint64_t;
+
+enum class MessageId : ::std::uint64_t;
+
+namespace MultiVersion {
+
+}  // namespace MultiVersion
+
+
+template <class Storage>
+class GenericMultiVersionView;
+
+namespace Axes {
+
+}  // namespace Axes
+
+
+template <class Storage>
+class GenericAxesView;
+
+namespace AxisPair {
+
+}  // namespace AxisPair
+
+
+template <class Storage>
+class GenericAxisPairView;
+
+namespace AxesEnvelope {
+
+}  // namespace AxesEnvelope
+
+
+template <class Storage>
+class GenericAxesEnvelopeView;
+
+enum class AxisType : ::std::int64_t;
+
+namespace Axis {
+
+}  // namespace Axis
+
+
+template <class Storage>
+class GenericAxisView;
+
+namespace Config {
+
+}  // namespace Config
+
+
+template <class Storage>
+class GenericConfigView;
+
+namespace ConfigVX {
+namespace EmbossReservedAnonymousField1 {
+
+}  // namespace EmbossReservedAnonymousField1
+
+
+template <class Storage>
+class GenericEmbossReservedAnonymousField1View;
+
+
+}  // namespace ConfigVX
+
+
+template <class Storage>
+class GenericConfigVXView;
+
+namespace StructWithUnusedParameter {
+
+}  // namespace StructWithUnusedParameter
+
+
+template <class Storage>
+class GenericStructWithUnusedParameterView;
+
+namespace StructContainingStructWithUnusedParameter {
+
+}  // namespace StructContainingStructWithUnusedParameter
+
+
+template <class Storage>
+class GenericStructContainingStructWithUnusedParameterView;
+
+namespace BiasedValue {
+
+}  // namespace BiasedValue
+
+
+template <class Storage>
+class GenericBiasedValueView;
+
+namespace VirtualFirstFieldWithParam {
+
+}  // namespace VirtualFirstFieldWithParam
+
+
+template <class Storage>
+class GenericVirtualFirstFieldWithParamView;
+
+namespace ConstVirtualFirstFieldWithParam {
+
+}  // namespace ConstVirtualFirstFieldWithParam
+
+
+template <class Storage>
+class GenericConstVirtualFirstFieldWithParamView;
+
+namespace SizedArrayOfBiasedValues {
+
+}  // namespace SizedArrayOfBiasedValues
+
+
+template <class Storage>
+class GenericSizedArrayOfBiasedValuesView;
+
+
+enum class Product : ::std::uint64_t {
+  VERSION_1 = static_cast</**/::std::int32_t>(0LL),
+  VERSION_2 = static_cast</**/::std::int32_t>(10LL),
+  VERSION_X = static_cast</**/::std::int32_t>(23LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<Product> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   Product *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("VERSION_1", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Product::VERSION_1;
+      return true;
+    }
+
+    if (!strcmp("VERSION_2", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Product::VERSION_2;
+      return true;
+    }
+
+    if (!strcmp("VERSION_X", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Product::VERSION_X;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      Product emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Product::VERSION_1: return "VERSION_1";
+
+      case Product::VERSION_2: return "VERSION_2";
+
+      case Product::VERSION_X: return "VERSION_X";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(Product emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Product::VERSION_1: return true;
+
+      case Product::VERSION_2: return true;
+
+      case Product::VERSION_X: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       Product emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<Product>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    Product *emboss_reserved_local_result) {
+  return EnumTraits<Product>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    Product emboss_reserved_local_value) {
+  return EnumTraits<Product>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(Product emboss_reserved_local_value) {
+  return EnumTraits<Product>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    Product emboss_reserved_local_value) {
+  return EnumTraits<Product>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+enum class MessageId : ::std::uint64_t {
+  AXIS = static_cast</**/::std::int32_t>(0LL),
+  CONFIG = static_cast</**/::std::int32_t>(1LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<MessageId> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   MessageId *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("AXIS", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = MessageId::AXIS;
+      return true;
+    }
+
+    if (!strcmp("CONFIG", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = MessageId::CONFIG;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      MessageId emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case MessageId::AXIS: return "AXIS";
+
+      case MessageId::CONFIG: return "CONFIG";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(MessageId emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case MessageId::AXIS: return true;
+
+      case MessageId::CONFIG: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       MessageId emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<MessageId>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    MessageId *emboss_reserved_local_result) {
+  return EnumTraits<MessageId>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    MessageId emboss_reserved_local_value) {
+  return EnumTraits<MessageId>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(MessageId emboss_reserved_local_value) {
+  return EnumTraits<MessageId>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    MessageId emboss_reserved_local_value) {
+  return EnumTraits<MessageId>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+
+
+
+
+
+
+namespace MultiVersion {
+
+}  // namespace MultiVersion
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericMultiVersionView;
+
+template <class Storage>
+class GenericMultiVersionView final {
+ public:
+  GenericMultiVersionView() : backing_() {}
+  explicit GenericMultiVersionView(
+      ::emboss::test::Product product,  Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) , product_(product)
+        , parameters_initialized_(true) {}
+
+  template <typename OtherStorage>
+  GenericMultiVersionView(
+      const GenericMultiVersionView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+        , product_(emboss_reserved_local_other.product_)
+, parameters_initialized_(emboss_reserved_local_other.parameters_initialized_) {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericMultiVersionView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericMultiVersionView(
+      ::emboss::test::Product product,  Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) , product_(product)
+        , parameters_initialized_(true) {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericMultiVersionView(
+      ::emboss::test::Product product,  Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) , product_(product)
+        , parameters_initialized_(true) {}
+
+  template <typename OtherStorage>
+  GenericMultiVersionView<Storage> &operator=(
+      const GenericMultiVersionView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+if (!parameters_initialized_) return false;
+    if (!has_message_id().Known()) return false;
+    if (has_message_id().ValueOrDefault() && !message_id().Ok()) return false;
+
+
+    if (!has_axes().Known()) return false;
+    if (has_axes().ValueOrDefault() && !axes().Ok()) return false;
+
+
+    if (!has_config().Known()) return false;
+    if (has_config().ValueOrDefault() && !config().Ok()) return false;
+
+
+    if (!has_config_vx().Known()) return false;
+    if (has_config_vx().ValueOrDefault() && !config_vx().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericMultiVersionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_product().Known()) return false;
+    if (!emboss_reserved_local_other.has_product().Known()) return false;
+
+    if (emboss_reserved_local_other.has_product().ValueOrDefault() &&
+        !has_product().ValueOrDefault())
+      return false;
+    if (has_product().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_product().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_product().ValueOrDefault() &&
+        has_product().ValueOrDefault() &&
+        !product().Equals(emboss_reserved_local_other.product()))
+      return false;
+
+
+
+    if (!has_message_id().Known()) return false;
+    if (!emboss_reserved_local_other.has_message_id().Known()) return false;
+
+    if (emboss_reserved_local_other.has_message_id().ValueOrDefault() &&
+        !has_message_id().ValueOrDefault())
+      return false;
+    if (has_message_id().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_message_id().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_message_id().ValueOrDefault() &&
+        has_message_id().ValueOrDefault() &&
+        !message_id().Equals(emboss_reserved_local_other.message_id()))
+      return false;
+
+
+
+    if (!has_axes().Known()) return false;
+    if (!emboss_reserved_local_other.has_axes().Known()) return false;
+
+    if (emboss_reserved_local_other.has_axes().ValueOrDefault() &&
+        !has_axes().ValueOrDefault())
+      return false;
+    if (has_axes().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_axes().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_axes().ValueOrDefault() &&
+        has_axes().ValueOrDefault() &&
+        !axes().Equals(emboss_reserved_local_other.axes()))
+      return false;
+
+
+
+    if (!has_config().Known()) return false;
+    if (!emboss_reserved_local_other.has_config().Known()) return false;
+
+    if (emboss_reserved_local_other.has_config().ValueOrDefault() &&
+        !has_config().ValueOrDefault())
+      return false;
+    if (has_config().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_config().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_config().ValueOrDefault() &&
+        has_config().ValueOrDefault() &&
+        !config().Equals(emboss_reserved_local_other.config()))
+      return false;
+
+
+
+    if (!has_config_vx().Known()) return false;
+    if (!emboss_reserved_local_other.has_config_vx().Known()) return false;
+
+    if (emboss_reserved_local_other.has_config_vx().ValueOrDefault() &&
+        !has_config_vx().ValueOrDefault())
+      return false;
+    if (has_config_vx().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_config_vx().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_config_vx().ValueOrDefault() &&
+        has_config_vx().ValueOrDefault() &&
+        !config_vx().Equals(emboss_reserved_local_other.config_vx()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericMultiVersionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_product().ValueOr(false) &&
+        !has_product().ValueOr(false))
+      return false;
+    if (has_product().ValueOr(false) &&
+        !emboss_reserved_local_other.has_product().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_product().ValueOr(false) &&
+        has_product().ValueOr(false) &&
+        !product().UncheckedEquals(emboss_reserved_local_other.product()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_message_id().ValueOr(false) &&
+        !has_message_id().ValueOr(false))
+      return false;
+    if (has_message_id().ValueOr(false) &&
+        !emboss_reserved_local_other.has_message_id().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_message_id().ValueOr(false) &&
+        has_message_id().ValueOr(false) &&
+        !message_id().UncheckedEquals(emboss_reserved_local_other.message_id()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_axes().ValueOr(false) &&
+        !has_axes().ValueOr(false))
+      return false;
+    if (has_axes().ValueOr(false) &&
+        !emboss_reserved_local_other.has_axes().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_axes().ValueOr(false) &&
+        has_axes().ValueOr(false) &&
+        !axes().UncheckedEquals(emboss_reserved_local_other.axes()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_config().ValueOr(false) &&
+        !has_config().ValueOr(false))
+      return false;
+    if (has_config().ValueOr(false) &&
+        !emboss_reserved_local_other.has_config().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_config().ValueOr(false) &&
+        has_config().ValueOr(false) &&
+        !config().UncheckedEquals(emboss_reserved_local_other.config()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_config_vx().ValueOr(false) &&
+        !has_config_vx().ValueOr(false))
+      return false;
+    if (has_config_vx().ValueOr(false) &&
+        !emboss_reserved_local_other.has_config_vx().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_config_vx().ValueOr(false) &&
+        has_config_vx().ValueOr(false) &&
+        !config_vx().UncheckedEquals(emboss_reserved_local_other.config_vx()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericMultiVersionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericMultiVersionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericMultiVersionView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "message_id") {
+        if (!message_id().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "axes") {
+        if (!axes().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "config") {
+        if (!config().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "config_vx") {
+        if (!config_vx().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_message_id().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          message_id().IsAggregate() || message_id().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("message_id: ");
+        message_id().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !message_id().IsAggregate() && !message_id().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# message_id: UNREADABLE\n");
+      }
+    }
+
+    if (has_axes().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          axes().IsAggregate() || axes().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("axes: ");
+        axes().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !axes().IsAggregate() && !axes().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# axes: UNREADABLE\n");
+      }
+    }
+
+    if (has_config().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          config().IsAggregate() || config().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("config: ");
+        config().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !config().IsAggregate() && !config().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# config: UNREADABLE\n");
+      }
+    }
+
+    if (has_config_vx().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          config_vx().IsAggregate() || config_vx().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("config_vx: ");
+        config_vx().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !config_vx().IsAggregate() && !config_vx().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# config_vx: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ private:
+  constexpr ::emboss::support::MaybeConstantView</**/ ::emboss::test::Product>
+  product() const {
+    return parameters_initialized_
+               ? ::emboss::support::MaybeConstantView</**/ ::emboss::test::Product>(
+                     product_)
+               : ::emboss::support::MaybeConstantView</**/ ::emboss::test::Product>();
+  }
+  constexpr ::emboss::support::Maybe<bool> has_product() const {
+    return ::emboss::support::Maybe<bool>(parameters_initialized_);
+  }
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::MessageId,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ message_id() const;
+  ::emboss::support::Maybe<bool> has_message_id() const;
+
+ public:
+  typename ::emboss::test::GenericAxesView<typename Storage::template OffsetStorageType</**/0, 1>>
+
+ axes() const;
+  ::emboss::support::Maybe<bool> has_axes() const;
+
+ public:
+  typename ::emboss::test::GenericConfigView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 32>>
+
+ config() const;
+  ::emboss::support::Maybe<bool> has_config() const;
+
+ public:
+  typename ::emboss::test::GenericConfigVXView<typename Storage::template OffsetStorageType</**/0, 1>>
+
+ config_vx() const;
+  ::emboss::support::Maybe<bool> has_config_vx() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericMultiVersionView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.message_id();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::emboss::test::MessageId>(static_cast</**/::emboss::test::MessageId>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::MessageId>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Equal</**/::emboss::test::MessageId, bool, ::emboss::test::MessageId, ::emboss::test::MessageId>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::emboss::test::MessageId>(static_cast</**/::emboss::test::MessageId>(0)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(13LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Equal</**/::emboss::test::MessageId, bool, ::emboss::test::MessageId, ::emboss::test::MessageId>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::emboss::test::MessageId>(static_cast</**/::emboss::test::MessageId>(1)));
+      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_5, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_7 = view_.product();
+      const auto emboss_reserved_local_subexpr_8 = (emboss_reserved_local_subexpr_7.Ok()    ? ::emboss::support::Maybe</**/::emboss::test::Product>(static_cast</**/::emboss::test::Product>(emboss_reserved_local_subexpr_7.UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::Product>());
+      const auto emboss_reserved_local_subexpr_9 = ::emboss::support::Equal</**/::emboss::test::Product, bool, ::emboss::test::Product, ::emboss::test::Product>(emboss_reserved_local_subexpr_8, ::emboss::support::Maybe</**/::emboss::test::Product>(static_cast</**/::emboss::test::Product>(23)));
+      const auto emboss_reserved_local_subexpr_10 = ::emboss::support::And</**/bool, bool, bool, bool>(emboss_reserved_local_subexpr_9, emboss_reserved_local_subexpr_5);
+      const auto emboss_reserved_local_subexpr_11 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_10, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(9LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_12 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_4, emboss_reserved_local_subexpr_6, emboss_reserved_local_subexpr_11);
+
+      return emboss_reserved_local_subexpr_12;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericMultiVersionView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  ::emboss::test::Product product_;
+  bool parameters_initialized_ = false;
+
+  template <class OtherStorage>
+  friend class GenericMultiVersionView;
+};
+using MultiVersionView =
+    GenericMultiVersionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using MultiVersionWriter =
+    GenericMultiVersionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericMultiVersionView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericMultiVersionView<
+    GenericMultiVersionView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericMultiVersionView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeMultiVersionView(::emboss::test::Product product,  T &&emboss_reserved_local_arg) {
+  return GenericMultiVersionView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+      ::std::forward</**/::emboss::test::Product>(product), ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericMultiVersionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeMultiVersionView(::emboss::test::Product product,  T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericMultiVersionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+      ::std::forward</**/::emboss::test::Product>(product), emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericMultiVersionView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedMultiVersionView(
+    ::emboss::test::Product product,  T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericMultiVersionView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+      ::std::forward</**/::emboss::test::Product>(product), emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+
+
+namespace Axes {
+
+}  // namespace Axes
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericAxesView;
+
+template <class Storage>
+class GenericAxesView final {
+ public:
+  GenericAxesView() : backing_() {}
+  explicit GenericAxesView(
+      ::std::int32_t axes,  Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) , axes_(axes)
+        , parameters_initialized_(true) {}
+
+  template <typename OtherStorage>
+  GenericAxesView(
+      const GenericAxesView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+        , axes_(emboss_reserved_local_other.axes_)
+, parameters_initialized_(emboss_reserved_local_other.parameters_initialized_) {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericAxesView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericAxesView(
+      ::std::int32_t axes,  Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) , axes_(axes)
+        , parameters_initialized_(true) {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericAxesView(
+      ::std::int32_t axes,  Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) , axes_(axes)
+        , parameters_initialized_(true) {}
+
+  template <typename OtherStorage>
+  GenericAxesView<Storage> &operator=(
+      const GenericAxesView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+if (!parameters_initialized_) return false;
+    if (!has_values().Known()) return false;
+    if (has_values().ValueOrDefault() && !values().Ok()) return false;
+
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_y().Known()) return false;
+    if (has_y().ValueOrDefault() && !y().Ok()) return false;
+
+
+    if (!has_z().Known()) return false;
+    if (has_z().ValueOrDefault() && !z().Ok()) return false;
+
+
+    if (!has_axis_count_plus_one().Known()) return false;
+    if (has_axis_count_plus_one().ValueOrDefault() && !axis_count_plus_one().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericAxesView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_axes().Known()) return false;
+    if (!emboss_reserved_local_other.has_axes().Known()) return false;
+
+    if (emboss_reserved_local_other.has_axes().ValueOrDefault() &&
+        !has_axes().ValueOrDefault())
+      return false;
+    if (has_axes().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_axes().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_axes().ValueOrDefault() &&
+        has_axes().ValueOrDefault() &&
+        !axes().Equals(emboss_reserved_local_other.axes()))
+      return false;
+
+
+
+    if (!has_values().Known()) return false;
+    if (!emboss_reserved_local_other.has_values().Known()) return false;
+
+    if (emboss_reserved_local_other.has_values().ValueOrDefault() &&
+        !has_values().ValueOrDefault())
+      return false;
+    if (has_values().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_values().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_values().ValueOrDefault() &&
+        has_values().ValueOrDefault() &&
+        !values().Equals(emboss_reserved_local_other.values()))
+      return false;
+
+
+
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_y().Known()) return false;
+    if (!emboss_reserved_local_other.has_y().Known()) return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
+        !has_y().ValueOrDefault())
+      return false;
+    if (has_y().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_y().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
+        has_y().ValueOrDefault() &&
+        !y().Equals(emboss_reserved_local_other.y()))
+      return false;
+
+
+
+    if (!has_z().Known()) return false;
+    if (!emboss_reserved_local_other.has_z().Known()) return false;
+
+    if (emboss_reserved_local_other.has_z().ValueOrDefault() &&
+        !has_z().ValueOrDefault())
+      return false;
+    if (has_z().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_z().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_z().ValueOrDefault() &&
+        has_z().ValueOrDefault() &&
+        !z().Equals(emboss_reserved_local_other.z()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericAxesView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_axes().ValueOr(false) &&
+        !has_axes().ValueOr(false))
+      return false;
+    if (has_axes().ValueOr(false) &&
+        !emboss_reserved_local_other.has_axes().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_axes().ValueOr(false) &&
+        has_axes().ValueOr(false) &&
+        !axes().UncheckedEquals(emboss_reserved_local_other.axes()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_values().ValueOr(false) &&
+        !has_values().ValueOr(false))
+      return false;
+    if (has_values().ValueOr(false) &&
+        !emboss_reserved_local_other.has_values().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_values().ValueOr(false) &&
+        has_values().ValueOr(false) &&
+        !values().UncheckedEquals(emboss_reserved_local_other.values()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
+        !has_y().ValueOr(false))
+      return false;
+    if (has_y().ValueOr(false) &&
+        !emboss_reserved_local_other.has_y().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
+        has_y().ValueOr(false) &&
+        !y().UncheckedEquals(emboss_reserved_local_other.y()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_z().ValueOr(false) &&
+        !has_z().ValueOr(false))
+      return false;
+    if (has_z().ValueOr(false) &&
+        !emboss_reserved_local_other.has_z().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_z().ValueOr(false) &&
+        has_z().ValueOr(false) &&
+        !z().UncheckedEquals(emboss_reserved_local_other.z()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericAxesView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericAxesView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericAxesView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "values") {
+        if (!values().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "y") {
+        if (!y().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "z") {
+        if (!z().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_values().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          values().IsAggregate() || values().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("values: ");
+        values().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !values().IsAggregate() && !values().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# values: UNREADABLE\n");
+      }
+    }
+
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_y().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          y().IsAggregate() || y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("y: ");
+        y().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !y().IsAggregate() && !y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# y: UNREADABLE\n");
+      }
+    }
+
+    if (has_z().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          z().IsAggregate() || z().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("z: ");
+        z().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !z().IsAggregate() && !z().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# z: UNREADABLE\n");
+      }
+    }
+
+    if (has_axis_count_plus_one().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          axis_count_plus_one().IsAggregate() || axis_count_plus_one().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# axis_count_plus_one: ");
+        axis_count_plus_one().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# axis_count_plus_one: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ private:
+  constexpr ::emboss::support::MaybeConstantView</**/ ::std::int32_t>
+  axes() const {
+    return parameters_initialized_
+               ? ::emboss::support::MaybeConstantView</**/ ::std::int32_t>(
+                     axes_)
+               : ::emboss::support::MaybeConstantView</**/ ::std::int32_t>();
+  }
+  constexpr ::emboss::support::Maybe<bool> has_axes() const {
+    return ::emboss::support::Maybe<bool>(parameters_initialized_);
+  }
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericAxisView<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/4, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 4,
+    8 , ::emboss::test::AxisType>
+
+ values() const;
+  ::emboss::support::Maybe<bool> has_values() const;
+
+ public:
+  typename ::emboss::test::GenericAxisView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::test::GenericAxisView<typename Storage::template OffsetStorageType</**/0, 4>>
+
+ y() const;
+  ::emboss::support::Maybe<bool> has_y() const;
+
+ public:
+  typename ::emboss::test::GenericAxisView<typename Storage::template OffsetStorageType</**/0, 8>>
+
+ z() const;
+  ::emboss::support::Maybe<bool> has_z() const;
+
+ public:
+  class EmbossReservedVirtualAxisCountPlusOneView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedVirtualAxisCountPlusOneView(
+        const GenericAxesView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualAxisCountPlusOneView() = delete;
+    EmbossReservedVirtualAxisCountPlusOneView(const EmbossReservedVirtualAxisCountPlusOneView &) = default;
+    EmbossReservedVirtualAxisCountPlusOneView(EmbossReservedVirtualAxisCountPlusOneView &&) = default;
+    EmbossReservedVirtualAxisCountPlusOneView &operator=(const EmbossReservedVirtualAxisCountPlusOneView &) =
+        default;
+    EmbossReservedVirtualAxisCountPlusOneView &operator=(EmbossReservedVirtualAxisCountPlusOneView &&) =
+        default;
+    ~EmbossReservedVirtualAxisCountPlusOneView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_axis_count_plus_one().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.axes();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+
+      return emboss_reserved_local_subexpr_3;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericAxesView view_;
+  };
+  EmbossReservedVirtualAxisCountPlusOneView axis_count_plus_one() const;
+  ::emboss::support::Maybe<bool> has_axis_count_plus_one() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericAxesView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.axes();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Product</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), emboss_reserved_local_subexpr_3);
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_4, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_6, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_8 = ::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      const auto emboss_reserved_local_subexpr_9 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_8, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_10 = ::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)));
+      const auto emboss_reserved_local_subexpr_11 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_10, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(12LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_12 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), emboss_reserved_local_subexpr_5, emboss_reserved_local_subexpr_7, emboss_reserved_local_subexpr_9, emboss_reserved_local_subexpr_11);
+
+      return emboss_reserved_local_subexpr_12;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericAxesView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  ::std::int32_t axes_;
+  bool parameters_initialized_ = false;
+
+  template <class OtherStorage>
+  friend class GenericAxesView;
+};
+using AxesView =
+    GenericAxesView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using AxesWriter =
+    GenericAxesView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericAxesView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericAxesView<
+    GenericAxesView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericAxesView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeAxesView(::std::int32_t axes,  T &&emboss_reserved_local_arg) {
+  return GenericAxesView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+      ::std::forward</**/::std::int32_t>(axes), ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericAxesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeAxesView(::std::int32_t axes,  T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericAxesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+      ::std::forward</**/::std::int32_t>(axes), emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericAxesView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedAxesView(
+    ::std::int32_t axes,  T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericAxesView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+      ::std::forward</**/::std::int32_t>(axes), emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+
+namespace AxisPair {
+
+}  // namespace AxisPair
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericAxisPairView;
+
+template <class Storage>
+class GenericAxisPairView final {
+ public:
+  GenericAxisPairView() : backing_() {}
+  explicit GenericAxisPairView(
+      ::emboss::test::AxisType axis_type_a_parameter, ::emboss::test::AxisType axis_type_b_parameter,  Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) , axis_type_a_parameter_(axis_type_a_parameter)
+, axis_type_b_parameter_(axis_type_b_parameter)
+        , parameters_initialized_(true) {}
+
+  template <typename OtherStorage>
+  GenericAxisPairView(
+      const GenericAxisPairView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+        , axis_type_a_parameter_(emboss_reserved_local_other.axis_type_a_parameter_)
+, axis_type_b_parameter_(emboss_reserved_local_other.axis_type_b_parameter_)
+, parameters_initialized_(emboss_reserved_local_other.parameters_initialized_) {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericAxisPairView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericAxisPairView(
+      ::emboss::test::AxisType axis_type_a_parameter, ::emboss::test::AxisType axis_type_b_parameter,  Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) , axis_type_a_parameter_(axis_type_a_parameter)
+, axis_type_b_parameter_(axis_type_b_parameter)
+        , parameters_initialized_(true) {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericAxisPairView(
+      ::emboss::test::AxisType axis_type_a_parameter, ::emboss::test::AxisType axis_type_b_parameter,  Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) , axis_type_a_parameter_(axis_type_a_parameter)
+, axis_type_b_parameter_(axis_type_b_parameter)
+        , parameters_initialized_(true) {}
+
+  template <typename OtherStorage>
+  GenericAxisPairView<Storage> &operator=(
+      const GenericAxisPairView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+if (!parameters_initialized_) return false;
+    if (!has_axis_type_a().Known()) return false;
+    if (has_axis_type_a().ValueOrDefault() && !axis_type_a().Ok()) return false;
+
+
+    if (!has_axis_a().Known()) return false;
+    if (has_axis_a().ValueOrDefault() && !axis_a().Ok()) return false;
+
+
+    if (!has_axis_type_b().Known()) return false;
+    if (has_axis_type_b().ValueOrDefault() && !axis_type_b().Ok()) return false;
+
+
+    if (!has_axis_b().Known()) return false;
+    if (has_axis_b().ValueOrDefault() && !axis_b().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericAxisPairView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_axis_type_a_parameter().Known()) return false;
+    if (!emboss_reserved_local_other.has_axis_type_a_parameter().Known()) return false;
+
+    if (emboss_reserved_local_other.has_axis_type_a_parameter().ValueOrDefault() &&
+        !has_axis_type_a_parameter().ValueOrDefault())
+      return false;
+    if (has_axis_type_a_parameter().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_axis_type_a_parameter().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_axis_type_a_parameter().ValueOrDefault() &&
+        has_axis_type_a_parameter().ValueOrDefault() &&
+        !axis_type_a_parameter().Equals(emboss_reserved_local_other.axis_type_a_parameter()))
+      return false;
+
+
+
+    if (!has_axis_type_b_parameter().Known()) return false;
+    if (!emboss_reserved_local_other.has_axis_type_b_parameter().Known()) return false;
+
+    if (emboss_reserved_local_other.has_axis_type_b_parameter().ValueOrDefault() &&
+        !has_axis_type_b_parameter().ValueOrDefault())
+      return false;
+    if (has_axis_type_b_parameter().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_axis_type_b_parameter().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_axis_type_b_parameter().ValueOrDefault() &&
+        has_axis_type_b_parameter().ValueOrDefault() &&
+        !axis_type_b_parameter().Equals(emboss_reserved_local_other.axis_type_b_parameter()))
+      return false;
+
+
+
+    if (!has_axis_a().Known()) return false;
+    if (!emboss_reserved_local_other.has_axis_a().Known()) return false;
+
+    if (emboss_reserved_local_other.has_axis_a().ValueOrDefault() &&
+        !has_axis_a().ValueOrDefault())
+      return false;
+    if (has_axis_a().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_axis_a().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_axis_a().ValueOrDefault() &&
+        has_axis_a().ValueOrDefault() &&
+        !axis_a().Equals(emboss_reserved_local_other.axis_a()))
+      return false;
+
+
+
+    if (!has_axis_b().Known()) return false;
+    if (!emboss_reserved_local_other.has_axis_b().Known()) return false;
+
+    if (emboss_reserved_local_other.has_axis_b().ValueOrDefault() &&
+        !has_axis_b().ValueOrDefault())
+      return false;
+    if (has_axis_b().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_axis_b().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_axis_b().ValueOrDefault() &&
+        has_axis_b().ValueOrDefault() &&
+        !axis_b().Equals(emboss_reserved_local_other.axis_b()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericAxisPairView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_axis_type_a_parameter().ValueOr(false) &&
+        !has_axis_type_a_parameter().ValueOr(false))
+      return false;
+    if (has_axis_type_a_parameter().ValueOr(false) &&
+        !emboss_reserved_local_other.has_axis_type_a_parameter().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_axis_type_a_parameter().ValueOr(false) &&
+        has_axis_type_a_parameter().ValueOr(false) &&
+        !axis_type_a_parameter().UncheckedEquals(emboss_reserved_local_other.axis_type_a_parameter()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_axis_type_b_parameter().ValueOr(false) &&
+        !has_axis_type_b_parameter().ValueOr(false))
+      return false;
+    if (has_axis_type_b_parameter().ValueOr(false) &&
+        !emboss_reserved_local_other.has_axis_type_b_parameter().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_axis_type_b_parameter().ValueOr(false) &&
+        has_axis_type_b_parameter().ValueOr(false) &&
+        !axis_type_b_parameter().UncheckedEquals(emboss_reserved_local_other.axis_type_b_parameter()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_axis_a().ValueOr(false) &&
+        !has_axis_a().ValueOr(false))
+      return false;
+    if (has_axis_a().ValueOr(false) &&
+        !emboss_reserved_local_other.has_axis_a().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_axis_a().ValueOr(false) &&
+        has_axis_a().ValueOr(false) &&
+        !axis_a().UncheckedEquals(emboss_reserved_local_other.axis_a()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_axis_b().ValueOr(false) &&
+        !has_axis_b().ValueOr(false))
+      return false;
+    if (has_axis_b().ValueOr(false) &&
+        !emboss_reserved_local_other.has_axis_b().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_axis_b().ValueOr(false) &&
+        has_axis_b().ValueOr(false) &&
+        !axis_b().UncheckedEquals(emboss_reserved_local_other.axis_b()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericAxisPairView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericAxisPairView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericAxisPairView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "axis_a") {
+        if (!axis_a().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "axis_b") {
+        if (!axis_b().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_axis_type_a().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          axis_type_a().IsAggregate() || axis_type_a().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# axis_type_a: ");
+        axis_type_a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# axis_type_a: UNREADABLE\n");
+      }
+    }
+
+    if (has_axis_a().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          axis_a().IsAggregate() || axis_a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("axis_a: ");
+        axis_a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !axis_a().IsAggregate() && !axis_a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# axis_a: UNREADABLE\n");
+      }
+    }
+
+    if (has_axis_type_b().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          axis_type_b().IsAggregate() || axis_type_b().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# axis_type_b: ");
+        axis_type_b().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# axis_type_b: UNREADABLE\n");
+      }
+    }
+
+    if (has_axis_b().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          axis_b().IsAggregate() || axis_b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("axis_b: ");
+        axis_b().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !axis_b().IsAggregate() && !axis_b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# axis_b: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ private:
+  constexpr ::emboss::support::MaybeConstantView</**/ ::emboss::test::AxisType>
+  axis_type_a_parameter() const {
+    return parameters_initialized_
+               ? ::emboss::support::MaybeConstantView</**/ ::emboss::test::AxisType>(
+                     axis_type_a_parameter_)
+               : ::emboss::support::MaybeConstantView</**/ ::emboss::test::AxisType>();
+  }
+  constexpr ::emboss::support::Maybe<bool> has_axis_type_a_parameter() const {
+    return ::emboss::support::Maybe<bool>(parameters_initialized_);
+  }
+
+ private:
+  constexpr ::emboss::support::MaybeConstantView</**/ ::emboss::test::AxisType>
+  axis_type_b_parameter() const {
+    return parameters_initialized_
+               ? ::emboss::support::MaybeConstantView</**/ ::emboss::test::AxisType>(
+                     axis_type_b_parameter_)
+               : ::emboss::support::MaybeConstantView</**/ ::emboss::test::AxisType>();
+  }
+  constexpr ::emboss::support::Maybe<bool> has_axis_type_b_parameter() const {
+    return ::emboss::support::Maybe<bool>(parameters_initialized_);
+  }
+
+ public:
+  class EmbossReservedVirtualAxisTypeAView final {
+   public:
+    using ValueType = ::emboss::test::AxisType;
+
+    explicit EmbossReservedVirtualAxisTypeAView(
+        const GenericAxisPairView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualAxisTypeAView() = delete;
+    EmbossReservedVirtualAxisTypeAView(const EmbossReservedVirtualAxisTypeAView &) = default;
+    EmbossReservedVirtualAxisTypeAView(EmbossReservedVirtualAxisTypeAView &&) = default;
+    EmbossReservedVirtualAxisTypeAView &operator=(const EmbossReservedVirtualAxisTypeAView &) =
+        default;
+    EmbossReservedVirtualAxisTypeAView &operator=(EmbossReservedVirtualAxisTypeAView &&) =
+        default;
+    ~EmbossReservedVirtualAxisTypeAView() = default;
+
+    ::emboss::test::AxisType Read() const {
+      EMBOSS_CHECK(view_.has_axis_type_a().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::emboss::test::AxisType UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteEnumViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::emboss::test::AxisType> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.axis_type_a_parameter();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::emboss::test::AxisType>(static_cast</**/::emboss::test::AxisType>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::AxisType>());
+
+      return emboss_reserved_local_subexpr_2;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::emboss::test::AxisType emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericAxisPairView view_;
+  };
+  EmbossReservedVirtualAxisTypeAView axis_type_a() const;
+  ::emboss::support::Maybe<bool> has_axis_type_a() const;
+
+ public:
+  typename ::emboss::test::GenericAxisView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ axis_a() const;
+  ::emboss::support::Maybe<bool> has_axis_a() const;
+
+ public:
+  class EmbossReservedVirtualAxisTypeBView final {
+   public:
+    using ValueType = ::emboss::test::AxisType;
+
+    explicit EmbossReservedVirtualAxisTypeBView(
+        const GenericAxisPairView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualAxisTypeBView() = delete;
+    EmbossReservedVirtualAxisTypeBView(const EmbossReservedVirtualAxisTypeBView &) = default;
+    EmbossReservedVirtualAxisTypeBView(EmbossReservedVirtualAxisTypeBView &&) = default;
+    EmbossReservedVirtualAxisTypeBView &operator=(const EmbossReservedVirtualAxisTypeBView &) =
+        default;
+    EmbossReservedVirtualAxisTypeBView &operator=(EmbossReservedVirtualAxisTypeBView &&) =
+        default;
+    ~EmbossReservedVirtualAxisTypeBView() = default;
+
+    ::emboss::test::AxisType Read() const {
+      EMBOSS_CHECK(view_.has_axis_type_b().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::emboss::test::AxisType UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteEnumViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::emboss::test::AxisType> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.axis_type_b_parameter();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::emboss::test::AxisType>(static_cast</**/::emboss::test::AxisType>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::AxisType>());
+
+      return emboss_reserved_local_subexpr_2;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::emboss::test::AxisType emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericAxisPairView view_;
+  };
+  EmbossReservedVirtualAxisTypeBView axis_type_b() const;
+  ::emboss::support::Maybe<bool> has_axis_type_b() const;
+
+ public:
+  typename ::emboss::test::GenericAxisView<typename Storage::template OffsetStorageType</**/0, 4>>
+
+ axis_b() const;
+  ::emboss::support::Maybe<bool> has_axis_b() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  ::emboss::test::AxisType axis_type_a_parameter_;
+::emboss::test::AxisType axis_type_b_parameter_;
+  bool parameters_initialized_ = false;
+
+  template <class OtherStorage>
+  friend class GenericAxisPairView;
+};
+using AxisPairView =
+    GenericAxisPairView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using AxisPairWriter =
+    GenericAxisPairView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericAxisPairView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericAxisPairView<
+    GenericAxisPairView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericAxisPairView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeAxisPairView(::emboss::test::AxisType axis_type_a_parameter, ::emboss::test::AxisType axis_type_b_parameter,  T &&emboss_reserved_local_arg) {
+  return GenericAxisPairView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+      ::std::forward</**/::emboss::test::AxisType>(axis_type_a_parameter),::std::forward</**/::emboss::test::AxisType>(axis_type_b_parameter), ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericAxisPairView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeAxisPairView(::emboss::test::AxisType axis_type_a_parameter, ::emboss::test::AxisType axis_type_b_parameter,  T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericAxisPairView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+      ::std::forward</**/::emboss::test::AxisType>(axis_type_a_parameter),::std::forward</**/::emboss::test::AxisType>(axis_type_b_parameter), emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericAxisPairView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedAxisPairView(
+    ::emboss::test::AxisType axis_type_a_parameter, ::emboss::test::AxisType axis_type_b_parameter,  T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericAxisPairView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+      ::std::forward</**/::emboss::test::AxisType>(axis_type_a_parameter),::std::forward</**/::emboss::test::AxisType>(axis_type_b_parameter), emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace AxesEnvelope {
+
+}  // namespace AxesEnvelope
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericAxesEnvelopeView;
+
+template <class Storage>
+class GenericAxesEnvelopeView final {
+ public:
+  GenericAxesEnvelopeView() : backing_() {}
+  explicit GenericAxesEnvelopeView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericAxesEnvelopeView(
+      const GenericAxesEnvelopeView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericAxesEnvelopeView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericAxesEnvelopeView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericAxesEnvelopeView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericAxesEnvelopeView<Storage> &operator=(
+      const GenericAxesEnvelopeView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_axis_count().Known()) return false;
+    if (has_axis_count().ValueOrDefault() && !axis_count().Ok()) return false;
+
+
+    if (!has_axes().Known()) return false;
+    if (has_axes().ValueOrDefault() && !axes().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericAxesEnvelopeView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_axis_count().Known()) return false;
+    if (!emboss_reserved_local_other.has_axis_count().Known()) return false;
+
+    if (emboss_reserved_local_other.has_axis_count().ValueOrDefault() &&
+        !has_axis_count().ValueOrDefault())
+      return false;
+    if (has_axis_count().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_axis_count().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_axis_count().ValueOrDefault() &&
+        has_axis_count().ValueOrDefault() &&
+        !axis_count().Equals(emboss_reserved_local_other.axis_count()))
+      return false;
+
+
+
+    if (!has_axes().Known()) return false;
+    if (!emboss_reserved_local_other.has_axes().Known()) return false;
+
+    if (emboss_reserved_local_other.has_axes().ValueOrDefault() &&
+        !has_axes().ValueOrDefault())
+      return false;
+    if (has_axes().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_axes().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_axes().ValueOrDefault() &&
+        has_axes().ValueOrDefault() &&
+        !axes().Equals(emboss_reserved_local_other.axes()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericAxesEnvelopeView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_axis_count().ValueOr(false) &&
+        !has_axis_count().ValueOr(false))
+      return false;
+    if (has_axis_count().ValueOr(false) &&
+        !emboss_reserved_local_other.has_axis_count().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_axis_count().ValueOr(false) &&
+        has_axis_count().ValueOr(false) &&
+        !axis_count().UncheckedEquals(emboss_reserved_local_other.axis_count()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_axes().ValueOr(false) &&
+        !has_axes().ValueOr(false))
+      return false;
+    if (has_axes().ValueOr(false) &&
+        !emboss_reserved_local_other.has_axes().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_axes().ValueOr(false) &&
+        has_axes().ValueOr(false) &&
+        !axes().UncheckedEquals(emboss_reserved_local_other.axes()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericAxesEnvelopeView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericAxesEnvelopeView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericAxesEnvelopeView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "axis_count") {
+        if (!axis_count().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "axes") {
+        if (!axes().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_axis_count().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          axis_count().IsAggregate() || axis_count().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("axis_count: ");
+        axis_count().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !axis_count().IsAggregate() && !axis_count().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# axis_count: UNREADABLE\n");
+      }
+    }
+
+    if (has_axes().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          axes().IsAggregate() || axes().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("axes: ");
+        axes().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !axes().IsAggregate() && !axes().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# axes: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ axis_count() const;
+  ::emboss::support::Maybe<bool> has_axis_count() const;
+
+ public:
+  typename ::emboss::test::GenericAxesView<typename Storage::template OffsetStorageType</**/0, 1>>
+
+ axes() const;
+  ::emboss::support::Maybe<bool> has_axes() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericAxesEnvelopeView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.axis_count();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Product</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_3);
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_4, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_5);
+
+      return emboss_reserved_local_subexpr_6;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericAxesEnvelopeView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericAxesEnvelopeView;
+};
+using AxesEnvelopeView =
+    GenericAxesEnvelopeView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using AxesEnvelopeWriter =
+    GenericAxesEnvelopeView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericAxesEnvelopeView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericAxesEnvelopeView<
+    GenericAxesEnvelopeView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericAxesEnvelopeView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeAxesEnvelopeView( T &&emboss_reserved_local_arg) {
+  return GenericAxesEnvelopeView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericAxesEnvelopeView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeAxesEnvelopeView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericAxesEnvelopeView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericAxesEnvelopeView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedAxesEnvelopeView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericAxesEnvelopeView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+enum class AxisType : ::std::int64_t {
+  GENERIC = static_cast</**/::std::int32_t>(-1LL),
+  X_AXIS = static_cast</**/::std::int32_t>(1LL),
+  Y_AXIS = static_cast</**/::std::int32_t>(2LL),
+  Z_AXIS = static_cast</**/::std::int32_t>(3LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<AxisType> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   AxisType *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("GENERIC", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = AxisType::GENERIC;
+      return true;
+    }
+
+    if (!strcmp("X_AXIS", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = AxisType::X_AXIS;
+      return true;
+    }
+
+    if (!strcmp("Y_AXIS", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = AxisType::Y_AXIS;
+      return true;
+    }
+
+    if (!strcmp("Z_AXIS", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = AxisType::Z_AXIS;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      AxisType emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case AxisType::GENERIC: return "GENERIC";
+
+      case AxisType::X_AXIS: return "X_AXIS";
+
+      case AxisType::Y_AXIS: return "Y_AXIS";
+
+      case AxisType::Z_AXIS: return "Z_AXIS";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(AxisType emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case AxisType::GENERIC: return true;
+
+      case AxisType::X_AXIS: return true;
+
+      case AxisType::Y_AXIS: return true;
+
+      case AxisType::Z_AXIS: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       AxisType emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<AxisType>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    AxisType *emboss_reserved_local_result) {
+  return EnumTraits<AxisType>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    AxisType emboss_reserved_local_value) {
+  return EnumTraits<AxisType>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(AxisType emboss_reserved_local_value) {
+  return EnumTraits<AxisType>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    AxisType emboss_reserved_local_value) {
+  return EnumTraits<AxisType>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+
+
+
+
+
+
+
+namespace Axis {
+
+}  // namespace Axis
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericAxisView;
+
+template <class Storage>
+class GenericAxisView final {
+ public:
+  GenericAxisView() : backing_() {}
+  explicit GenericAxisView(
+      ::emboss::test::AxisType axis_type_parameter,  Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) , axis_type_parameter_(axis_type_parameter)
+        , parameters_initialized_(true) {}
+
+  template <typename OtherStorage>
+  GenericAxisView(
+      const GenericAxisView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+        , axis_type_parameter_(emboss_reserved_local_other.axis_type_parameter_)
+, parameters_initialized_(emboss_reserved_local_other.parameters_initialized_) {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericAxisView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericAxisView(
+      ::emboss::test::AxisType axis_type_parameter,  Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) , axis_type_parameter_(axis_type_parameter)
+        , parameters_initialized_(true) {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericAxisView(
+      ::emboss::test::AxisType axis_type_parameter,  Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) , axis_type_parameter_(axis_type_parameter)
+        , parameters_initialized_(true) {}
+
+  template <typename OtherStorage>
+  GenericAxisView<Storage> &operator=(
+      const GenericAxisView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+if (!parameters_initialized_) return false;
+    if (!has_value().Known()) return false;
+    if (has_value().ValueOrDefault() && !value().Ok()) return false;
+
+
+    if (!has_axis_type().Known()) return false;
+    if (has_axis_type().ValueOrDefault() && !axis_type().Ok()) return false;
+
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_y().Known()) return false;
+    if (has_y().ValueOrDefault() && !y().Ok()) return false;
+
+
+    if (!has_z().Known()) return false;
+    if (has_z().ValueOrDefault() && !z().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericAxisView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_axis_type_parameter().Known()) return false;
+    if (!emboss_reserved_local_other.has_axis_type_parameter().Known()) return false;
+
+    if (emboss_reserved_local_other.has_axis_type_parameter().ValueOrDefault() &&
+        !has_axis_type_parameter().ValueOrDefault())
+      return false;
+    if (has_axis_type_parameter().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_axis_type_parameter().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_axis_type_parameter().ValueOrDefault() &&
+        has_axis_type_parameter().ValueOrDefault() &&
+        !axis_type_parameter().Equals(emboss_reserved_local_other.axis_type_parameter()))
+      return false;
+
+
+
+    if (!has_value().Known()) return false;
+    if (!emboss_reserved_local_other.has_value().Known()) return false;
+
+    if (emboss_reserved_local_other.has_value().ValueOrDefault() &&
+        !has_value().ValueOrDefault())
+      return false;
+    if (has_value().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_value().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_value().ValueOrDefault() &&
+        has_value().ValueOrDefault() &&
+        !value().Equals(emboss_reserved_local_other.value()))
+      return false;
+
+
+
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_y().Known()) return false;
+    if (!emboss_reserved_local_other.has_y().Known()) return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
+        !has_y().ValueOrDefault())
+      return false;
+    if (has_y().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_y().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
+        has_y().ValueOrDefault() &&
+        !y().Equals(emboss_reserved_local_other.y()))
+      return false;
+
+
+
+    if (!has_z().Known()) return false;
+    if (!emboss_reserved_local_other.has_z().Known()) return false;
+
+    if (emboss_reserved_local_other.has_z().ValueOrDefault() &&
+        !has_z().ValueOrDefault())
+      return false;
+    if (has_z().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_z().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_z().ValueOrDefault() &&
+        has_z().ValueOrDefault() &&
+        !z().Equals(emboss_reserved_local_other.z()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericAxisView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_axis_type_parameter().ValueOr(false) &&
+        !has_axis_type_parameter().ValueOr(false))
+      return false;
+    if (has_axis_type_parameter().ValueOr(false) &&
+        !emboss_reserved_local_other.has_axis_type_parameter().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_axis_type_parameter().ValueOr(false) &&
+        has_axis_type_parameter().ValueOr(false) &&
+        !axis_type_parameter().UncheckedEquals(emboss_reserved_local_other.axis_type_parameter()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_value().ValueOr(false) &&
+        !has_value().ValueOr(false))
+      return false;
+    if (has_value().ValueOr(false) &&
+        !emboss_reserved_local_other.has_value().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_value().ValueOr(false) &&
+        has_value().ValueOr(false) &&
+        !value().UncheckedEquals(emboss_reserved_local_other.value()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
+        !has_y().ValueOr(false))
+      return false;
+    if (has_y().ValueOr(false) &&
+        !emboss_reserved_local_other.has_y().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
+        has_y().ValueOr(false) &&
+        !y().UncheckedEquals(emboss_reserved_local_other.y()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_z().ValueOr(false) &&
+        !has_z().ValueOr(false))
+      return false;
+    if (has_z().ValueOr(false) &&
+        !emboss_reserved_local_other.has_z().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_z().ValueOr(false) &&
+        has_z().ValueOr(false) &&
+        !z().UncheckedEquals(emboss_reserved_local_other.z()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericAxisView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericAxisView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericAxisView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "value") {
+        if (!value().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "y") {
+        if (!y().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "z") {
+        if (!z().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_value().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          value().IsAggregate() || value().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("value: ");
+        value().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !value().IsAggregate() && !value().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# value: UNREADABLE\n");
+      }
+    }
+
+    if (has_axis_type().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          axis_type().IsAggregate() || axis_type().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# axis_type: ");
+        axis_type().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# axis_type: UNREADABLE\n");
+      }
+    }
+
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_y().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          y().IsAggregate() || y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("y: ");
+        y().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !y().IsAggregate() && !y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# y: UNREADABLE\n");
+      }
+    }
+
+    if (has_z().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          z().IsAggregate() || z().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("z: ");
+        z().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !z().IsAggregate() && !z().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# z: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ private:
+  constexpr ::emboss::support::MaybeConstantView</**/ ::emboss::test::AxisType>
+  axis_type_parameter() const {
+    return parameters_initialized_
+               ? ::emboss::support::MaybeConstantView</**/ ::emboss::test::AxisType>(
+                     axis_type_parameter_)
+               : ::emboss::support::MaybeConstantView</**/ ::emboss::test::AxisType>();
+  }
+  constexpr ::emboss::support::Maybe<bool> has_axis_type_parameter() const {
+    return ::emboss::support::Maybe<bool>(parameters_initialized_);
+  }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ value() const;
+  ::emboss::support::Maybe<bool> has_value() const;
+
+ public:
+  class EmbossReservedVirtualAxisTypeView final {
+   public:
+    using ValueType = ::emboss::test::AxisType;
+
+    explicit EmbossReservedVirtualAxisTypeView(
+        const GenericAxisView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualAxisTypeView() = delete;
+    EmbossReservedVirtualAxisTypeView(const EmbossReservedVirtualAxisTypeView &) = default;
+    EmbossReservedVirtualAxisTypeView(EmbossReservedVirtualAxisTypeView &&) = default;
+    EmbossReservedVirtualAxisTypeView &operator=(const EmbossReservedVirtualAxisTypeView &) =
+        default;
+    EmbossReservedVirtualAxisTypeView &operator=(EmbossReservedVirtualAxisTypeView &&) =
+        default;
+    ~EmbossReservedVirtualAxisTypeView() = default;
+
+    ::emboss::test::AxisType Read() const {
+      EMBOSS_CHECK(view_.has_axis_type().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::emboss::test::AxisType UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteEnumViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::emboss::test::AxisType> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.axis_type_parameter();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::emboss::test::AxisType>(static_cast</**/::emboss::test::AxisType>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::AxisType>());
+
+      return emboss_reserved_local_subexpr_2;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::emboss::test::AxisType emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericAxisView view_;
+  };
+  EmbossReservedVirtualAxisTypeView axis_type() const;
+  ::emboss::support::Maybe<bool> has_axis_type() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ y() const;
+  ::emboss::support::Maybe<bool> has_y() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ z() const;
+  ::emboss::support::Maybe<bool> has_z() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  ::emboss::test::AxisType axis_type_parameter_;
+  bool parameters_initialized_ = false;
+
+  template <class OtherStorage>
+  friend class GenericAxisView;
+};
+using AxisView =
+    GenericAxisView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using AxisWriter =
+    GenericAxisView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericAxisView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericAxisView<
+    GenericAxisView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericAxisView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeAxisView(::emboss::test::AxisType axis_type_parameter,  T &&emboss_reserved_local_arg) {
+  return GenericAxisView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+      ::std::forward</**/::emboss::test::AxisType>(axis_type_parameter), ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericAxisView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeAxisView(::emboss::test::AxisType axis_type_parameter,  T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericAxisView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+      ::std::forward</**/::emboss::test::AxisType>(axis_type_parameter), emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericAxisView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedAxisView(
+    ::emboss::test::AxisType axis_type_parameter,  T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericAxisView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+      ::std::forward</**/::emboss::test::AxisType>(axis_type_parameter), emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+namespace Config {
+
+}  // namespace Config
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericConfigView;
+
+template <class Storage>
+class GenericConfigView final {
+ public:
+  GenericConfigView() : backing_() {}
+  explicit GenericConfigView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericConfigView(
+      const GenericConfigView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericConfigView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericConfigView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericConfigView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericConfigView<Storage> &operator=(
+      const GenericConfigView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_power().Known()) return false;
+    if (has_power().ValueOrDefault() && !power().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBits().Known()) return false;
+    if (has_IntrinsicSizeInBits().ValueOrDefault() && !IntrinsicSizeInBits().Ok()) return false;
+
+
+    if (!has_MaxSizeInBits().Known()) return false;
+    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok()) return false;
+
+
+    if (!has_MinSizeInBits().Known()) return false;
+    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBits().Ok() &&
+           backing_.SizeInBits() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBits().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBits() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBits().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBits().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericConfigView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_power().Known()) return false;
+    if (!emboss_reserved_local_other.has_power().Known()) return false;
+
+    if (emboss_reserved_local_other.has_power().ValueOrDefault() &&
+        !has_power().ValueOrDefault())
+      return false;
+    if (has_power().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_power().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_power().ValueOrDefault() &&
+        has_power().ValueOrDefault() &&
+        !power().Equals(emboss_reserved_local_other.power()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericConfigView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_power().ValueOr(false) &&
+        !has_power().ValueOr(false))
+      return false;
+    if (has_power().ValueOr(false) &&
+        !emboss_reserved_local_other.has_power().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_power().ValueOr(false) &&
+        has_power().ValueOr(false) &&
+        !power().UncheckedEquals(emboss_reserved_local_other.power()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericConfigView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericConfigView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericConfigView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "power") {
+        if (!power().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_power().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          power().IsAggregate() || power().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("power: ");
+        power().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !power().IsAggregate() && !power().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# power: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 31>>
+
+ power() const;
+  ::emboss::support::Maybe<bool> has_power() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView IntrinsicSizeInBits() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBitsView() {}
+    EmbossReservedDollarVirtualMaxSizeInBitsView(const EmbossReservedDollarVirtualMaxSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView(EmbossReservedDollarVirtualMaxSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(const EmbossReservedDollarVirtualMaxSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(EmbossReservedDollarVirtualMaxSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBitsView MaxSizeInBits() {
+    return EmbossReservedDollarVirtualMaxSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBitsView() {}
+    EmbossReservedDollarVirtualMinSizeInBitsView(const EmbossReservedDollarVirtualMinSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView(EmbossReservedDollarVirtualMinSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(const EmbossReservedDollarVirtualMinSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(EmbossReservedDollarVirtualMinSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBitsView MinSizeInBits() {
+    return EmbossReservedDollarVirtualMinSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericConfigView;
+};
+using ConfigView =
+    GenericConfigView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ConfigWriter =
+    GenericConfigView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericConfigView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericConfigView<
+    GenericConfigView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericConfigView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeConfigView( T &&emboss_reserved_local_arg) {
+  return GenericConfigView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericConfigView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeConfigView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericConfigView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericConfigView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedConfigView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericConfigView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace ConfigVX {
+
+
+
+namespace EmbossReservedAnonymousField1 {
+
+}  // namespace EmbossReservedAnonymousField1
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View;
+
+template <class Storage>
+class GenericEmbossReservedAnonymousField1View final {
+ public:
+  GenericEmbossReservedAnonymousField1View() : backing_() {}
+  explicit GenericEmbossReservedAnonymousField1View(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEmbossReservedAnonymousField1View(
+      const GenericEmbossReservedAnonymousField1View<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericEmbossReservedAnonymousField1View(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericEmbossReservedAnonymousField1View(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEmbossReservedAnonymousField1View<Storage> &operator=(
+      const GenericEmbossReservedAnonymousField1View<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_power().Known()) return false;
+    if (has_power().ValueOrDefault() && !power().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBits().Known()) return false;
+    if (has_IntrinsicSizeInBits().ValueOrDefault() && !IntrinsicSizeInBits().Ok()) return false;
+
+
+    if (!has_MaxSizeInBits().Known()) return false;
+    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok()) return false;
+
+
+    if (!has_MinSizeInBits().Known()) return false;
+    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBits().Ok() &&
+           backing_.SizeInBits() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBits().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBits() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBits().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBits().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_power().Known()) return false;
+    if (!emboss_reserved_local_other.has_power().Known()) return false;
+
+    if (emboss_reserved_local_other.has_power().ValueOrDefault() &&
+        !has_power().ValueOrDefault())
+      return false;
+    if (has_power().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_power().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_power().ValueOrDefault() &&
+        has_power().ValueOrDefault() &&
+        !power().Equals(emboss_reserved_local_other.power()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_power().ValueOr(false) &&
+        !has_power().ValueOr(false))
+      return false;
+    if (has_power().ValueOr(false) &&
+        !emboss_reserved_local_other.has_power().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_power().ValueOr(false) &&
+        has_power().ValueOr(false) &&
+        !power().UncheckedEquals(emboss_reserved_local_other.power()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "power") {
+        if (!power().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_power().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          power().IsAggregate() || power().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("power: ");
+        power().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !power().IsAggregate() && !power().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# power: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 31>>
+
+ power() const;
+  ::emboss::support::Maybe<bool> has_power() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView IntrinsicSizeInBits() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBitsView() {}
+    EmbossReservedDollarVirtualMaxSizeInBitsView(const EmbossReservedDollarVirtualMaxSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView(EmbossReservedDollarVirtualMaxSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(const EmbossReservedDollarVirtualMaxSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(EmbossReservedDollarVirtualMaxSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBitsView MaxSizeInBits() {
+    return EmbossReservedDollarVirtualMaxSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBitsView() {}
+    EmbossReservedDollarVirtualMinSizeInBitsView(const EmbossReservedDollarVirtualMinSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView(EmbossReservedDollarVirtualMinSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(const EmbossReservedDollarVirtualMinSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(EmbossReservedDollarVirtualMinSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBitsView MinSizeInBits() {
+    return EmbossReservedDollarVirtualMinSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericEmbossReservedAnonymousField1View;
+};
+using EmbossReservedAnonymousField1View =
+    GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using EmbossReservedAnonymousField1Writer =
+    GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View<
+    GenericEmbossReservedAnonymousField1View<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericEmbossReservedAnonymousField1View<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeEmbossReservedAnonymousField1View( T &&emboss_reserved_local_arg) {
+  return GenericEmbossReservedAnonymousField1View<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeEmbossReservedAnonymousField1View( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericEmbossReservedAnonymousField1View<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedEmbossReservedAnonymousField1View(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericEmbossReservedAnonymousField1View<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+}  // namespace ConfigVX
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericConfigVXView;
+
+template <class Storage>
+class GenericConfigVXView final {
+ public:
+  GenericConfigVXView() : backing_() {}
+  explicit GenericConfigVXView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericConfigVXView(
+      const GenericConfigVXView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericConfigVXView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericConfigVXView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericConfigVXView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericConfigVXView<Storage> &operator=(
+      const GenericConfigVXView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_emboss_reserved_anonymous_field_1().Known()) return false;
+    if (has_emboss_reserved_anonymous_field_1().ValueOrDefault() && !emboss_reserved_anonymous_field_1().Ok()) return false;
+
+
+    if (!has_power().Known()) return false;
+    if (has_power().ValueOrDefault() && !power().Ok()) return false;
+
+
+    if (!has_gain().Known()) return false;
+    if (has_gain().ValueOrDefault() && !gain().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericConfigVXView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_emboss_reserved_anonymous_field_1().Known()) return false;
+    if (!emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().Known()) return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        !has_emboss_reserved_anonymous_field_1().ValueOrDefault())
+      return false;
+    if (has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        !emboss_reserved_anonymous_field_1().Equals(emboss_reserved_local_other.emboss_reserved_anonymous_field_1()))
+      return false;
+
+
+
+    if (!has_gain().Known()) return false;
+    if (!emboss_reserved_local_other.has_gain().Known()) return false;
+
+    if (emboss_reserved_local_other.has_gain().ValueOrDefault() &&
+        !has_gain().ValueOrDefault())
+      return false;
+    if (has_gain().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_gain().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_gain().ValueOrDefault() &&
+        has_gain().ValueOrDefault() &&
+        !gain().Equals(emboss_reserved_local_other.gain()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericConfigVXView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        !has_emboss_reserved_anonymous_field_1().ValueOr(false))
+      return false;
+    if (has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        !emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        !emboss_reserved_anonymous_field_1().UncheckedEquals(emboss_reserved_local_other.emboss_reserved_anonymous_field_1()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_gain().ValueOr(false) &&
+        !has_gain().ValueOr(false))
+      return false;
+    if (has_gain().ValueOr(false) &&
+        !emboss_reserved_local_other.has_gain().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_gain().ValueOr(false) &&
+        has_gain().ValueOr(false) &&
+        !gain().UncheckedEquals(emboss_reserved_local_other.gain()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericConfigVXView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericConfigVXView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericConfigVXView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "power") {
+        if (!power().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "gain") {
+        if (!gain().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_power().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          power().IsAggregate() || power().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("power: ");
+        power().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !power().IsAggregate() && !power().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# power: UNREADABLE\n");
+      }
+    }
+
+    if (has_gain().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          gain().IsAggregate() || gain().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("gain: ");
+        gain().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !gain().IsAggregate() && !gain().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# gain: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ private:
+  typename ::emboss::test::ConfigVX::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ emboss_reserved_anonymous_field_1() const;
+  ::emboss::support::Maybe<bool> has_emboss_reserved_anonymous_field_1() const;
+
+ public:
+  auto power() const -> decltype(this->emboss_reserved_anonymous_field_1().power()) {
+   return has_power().ValueOrDefault() ? emboss_reserved_anonymous_field_1().power()
+                                          : decltype(this->emboss_reserved_anonymous_field_1().power())();
+  }
+  ::emboss::support::Maybe<bool> has_power() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+ gain() const;
+  ::emboss::support::Maybe<bool> has_gain() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericConfigVXView;
+};
+using ConfigVXView =
+    GenericConfigVXView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ConfigVXWriter =
+    GenericConfigVXView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericConfigVXView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericConfigVXView<
+    GenericConfigVXView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericConfigVXView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeConfigVXView( T &&emboss_reserved_local_arg) {
+  return GenericConfigVXView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericConfigVXView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeConfigVXView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericConfigVXView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericConfigVXView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedConfigVXView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericConfigVXView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+namespace StructWithUnusedParameter {
+
+}  // namespace StructWithUnusedParameter
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructWithUnusedParameterView;
+
+template <class Storage>
+class GenericStructWithUnusedParameterView final {
+ public:
+  GenericStructWithUnusedParameterView() : backing_() {}
+  explicit GenericStructWithUnusedParameterView(
+      ::std::int32_t x,  Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) , x_(x)
+        , parameters_initialized_(true) {}
+
+  template <typename OtherStorage>
+  GenericStructWithUnusedParameterView(
+      const GenericStructWithUnusedParameterView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+        , x_(emboss_reserved_local_other.x_)
+, parameters_initialized_(emboss_reserved_local_other.parameters_initialized_) {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericStructWithUnusedParameterView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericStructWithUnusedParameterView(
+      ::std::int32_t x,  Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) , x_(x)
+        , parameters_initialized_(true) {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericStructWithUnusedParameterView(
+      ::std::int32_t x,  Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) , x_(x)
+        , parameters_initialized_(true) {}
+
+  template <typename OtherStorage>
+  GenericStructWithUnusedParameterView<Storage> &operator=(
+      const GenericStructWithUnusedParameterView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+if (!parameters_initialized_) return false;
+    if (!has_y().Known()) return false;
+    if (has_y().ValueOrDefault() && !y().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericStructWithUnusedParameterView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_y().Known()) return false;
+    if (!emboss_reserved_local_other.has_y().Known()) return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
+        !has_y().ValueOrDefault())
+      return false;
+    if (has_y().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_y().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
+        has_y().ValueOrDefault() &&
+        !y().Equals(emboss_reserved_local_other.y()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericStructWithUnusedParameterView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
+        !has_y().ValueOr(false))
+      return false;
+    if (has_y().ValueOr(false) &&
+        !emboss_reserved_local_other.has_y().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
+        has_y().ValueOr(false) &&
+        !y().UncheckedEquals(emboss_reserved_local_other.y()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericStructWithUnusedParameterView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericStructWithUnusedParameterView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericStructWithUnusedParameterView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "y") {
+        if (!y().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_y().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          y().IsAggregate() || y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("y: ");
+        y().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !y().IsAggregate() && !y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# y: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ private:
+  constexpr ::emboss::support::MaybeConstantView</**/ ::std::int32_t>
+  x() const {
+    return parameters_initialized_
+               ? ::emboss::support::MaybeConstantView</**/ ::std::int32_t>(
+                     x_)
+               : ::emboss::support::MaybeConstantView</**/ ::std::int32_t>();
+  }
+  constexpr ::emboss::support::Maybe<bool> has_x() const {
+    return ::emboss::support::Maybe<bool>(parameters_initialized_);
+  }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ y() const;
+  ::emboss::support::Maybe<bool> has_y() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  ::std::int32_t x_;
+  bool parameters_initialized_ = false;
+
+  template <class OtherStorage>
+  friend class GenericStructWithUnusedParameterView;
+};
+using StructWithUnusedParameterView =
+    GenericStructWithUnusedParameterView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using StructWithUnusedParameterWriter =
+    GenericStructWithUnusedParameterView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructWithUnusedParameterView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericStructWithUnusedParameterView<
+    GenericStructWithUnusedParameterView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericStructWithUnusedParameterView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeStructWithUnusedParameterView(::std::int32_t x,  T &&emboss_reserved_local_arg) {
+  return GenericStructWithUnusedParameterView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+      ::std::forward</**/::std::int32_t>(x), ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericStructWithUnusedParameterView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeStructWithUnusedParameterView(::std::int32_t x,  T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericStructWithUnusedParameterView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+      ::std::forward</**/::std::int32_t>(x), emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericStructWithUnusedParameterView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedStructWithUnusedParameterView(
+    ::std::int32_t x,  T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericStructWithUnusedParameterView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+      ::std::forward</**/::std::int32_t>(x), emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace StructContainingStructWithUnusedParameter {
+
+}  // namespace StructContainingStructWithUnusedParameter
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructContainingStructWithUnusedParameterView;
+
+template <class Storage>
+class GenericStructContainingStructWithUnusedParameterView final {
+ public:
+  GenericStructContainingStructWithUnusedParameterView() : backing_() {}
+  explicit GenericStructContainingStructWithUnusedParameterView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructContainingStructWithUnusedParameterView(
+      const GenericStructContainingStructWithUnusedParameterView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericStructContainingStructWithUnusedParameterView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericStructContainingStructWithUnusedParameterView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericStructContainingStructWithUnusedParameterView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructContainingStructWithUnusedParameterView<Storage> &operator=(
+      const GenericStructContainingStructWithUnusedParameterView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_swup().Known()) return false;
+    if (has_swup().ValueOrDefault() && !swup().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericStructContainingStructWithUnusedParameterView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_swup().Known()) return false;
+    if (!emboss_reserved_local_other.has_swup().Known()) return false;
+
+    if (emboss_reserved_local_other.has_swup().ValueOrDefault() &&
+        !has_swup().ValueOrDefault())
+      return false;
+    if (has_swup().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_swup().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_swup().ValueOrDefault() &&
+        has_swup().ValueOrDefault() &&
+        !swup().Equals(emboss_reserved_local_other.swup()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericStructContainingStructWithUnusedParameterView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_swup().ValueOr(false) &&
+        !has_swup().ValueOr(false))
+      return false;
+    if (has_swup().ValueOr(false) &&
+        !emboss_reserved_local_other.has_swup().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_swup().ValueOr(false) &&
+        has_swup().ValueOr(false) &&
+        !swup().UncheckedEquals(emboss_reserved_local_other.swup()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericStructContainingStructWithUnusedParameterView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericStructContainingStructWithUnusedParameterView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericStructContainingStructWithUnusedParameterView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "swup") {
+        if (!swup().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_swup().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          swup().IsAggregate() || swup().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("swup: ");
+        swup().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !swup().IsAggregate() && !swup().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# swup: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::test::GenericStructWithUnusedParameterView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ swup() const;
+  ::emboss::support::Maybe<bool> has_swup() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericStructContainingStructWithUnusedParameterView;
+};
+using StructContainingStructWithUnusedParameterView =
+    GenericStructContainingStructWithUnusedParameterView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using StructContainingStructWithUnusedParameterWriter =
+    GenericStructContainingStructWithUnusedParameterView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructContainingStructWithUnusedParameterView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericStructContainingStructWithUnusedParameterView<
+    GenericStructContainingStructWithUnusedParameterView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericStructContainingStructWithUnusedParameterView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeStructContainingStructWithUnusedParameterView( T &&emboss_reserved_local_arg) {
+  return GenericStructContainingStructWithUnusedParameterView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericStructContainingStructWithUnusedParameterView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeStructContainingStructWithUnusedParameterView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericStructContainingStructWithUnusedParameterView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericStructContainingStructWithUnusedParameterView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedStructContainingStructWithUnusedParameterView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericStructContainingStructWithUnusedParameterView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace BiasedValue {
+
+}  // namespace BiasedValue
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericBiasedValueView;
+
+template <class Storage>
+class GenericBiasedValueView final {
+ public:
+  GenericBiasedValueView() : backing_() {}
+  explicit GenericBiasedValueView(
+      ::std::int32_t bias,  Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) , bias_(bias)
+        , parameters_initialized_(true) {}
+
+  template <typename OtherStorage>
+  GenericBiasedValueView(
+      const GenericBiasedValueView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+        , bias_(emboss_reserved_local_other.bias_)
+, parameters_initialized_(emboss_reserved_local_other.parameters_initialized_) {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericBiasedValueView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericBiasedValueView(
+      ::std::int32_t bias,  Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) , bias_(bias)
+        , parameters_initialized_(true) {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericBiasedValueView(
+      ::std::int32_t bias,  Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) , bias_(bias)
+        , parameters_initialized_(true) {}
+
+  template <typename OtherStorage>
+  GenericBiasedValueView<Storage> &operator=(
+      const GenericBiasedValueView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+if (!parameters_initialized_) return false;
+    if (!has_raw_value().Known()) return false;
+    if (has_raw_value().ValueOrDefault() && !raw_value().Ok()) return false;
+
+
+    if (!has_value().Known()) return false;
+    if (has_value().ValueOrDefault() && !value().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericBiasedValueView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_bias().Known()) return false;
+    if (!emboss_reserved_local_other.has_bias().Known()) return false;
+
+    if (emboss_reserved_local_other.has_bias().ValueOrDefault() &&
+        !has_bias().ValueOrDefault())
+      return false;
+    if (has_bias().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_bias().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_bias().ValueOrDefault() &&
+        has_bias().ValueOrDefault() &&
+        !bias().Equals(emboss_reserved_local_other.bias()))
+      return false;
+
+
+
+    if (!has_raw_value().Known()) return false;
+    if (!emboss_reserved_local_other.has_raw_value().Known()) return false;
+
+    if (emboss_reserved_local_other.has_raw_value().ValueOrDefault() &&
+        !has_raw_value().ValueOrDefault())
+      return false;
+    if (has_raw_value().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_raw_value().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_raw_value().ValueOrDefault() &&
+        has_raw_value().ValueOrDefault() &&
+        !raw_value().Equals(emboss_reserved_local_other.raw_value()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericBiasedValueView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_bias().ValueOr(false) &&
+        !has_bias().ValueOr(false))
+      return false;
+    if (has_bias().ValueOr(false) &&
+        !emboss_reserved_local_other.has_bias().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_bias().ValueOr(false) &&
+        has_bias().ValueOr(false) &&
+        !bias().UncheckedEquals(emboss_reserved_local_other.bias()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_raw_value().ValueOr(false) &&
+        !has_raw_value().ValueOr(false))
+      return false;
+    if (has_raw_value().ValueOr(false) &&
+        !emboss_reserved_local_other.has_raw_value().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_raw_value().ValueOr(false) &&
+        has_raw_value().ValueOr(false) &&
+        !raw_value().UncheckedEquals(emboss_reserved_local_other.raw_value()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericBiasedValueView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericBiasedValueView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericBiasedValueView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "raw_value") {
+        if (!raw_value().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_raw_value().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          raw_value().IsAggregate() || raw_value().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("raw_value: ");
+        raw_value().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !raw_value().IsAggregate() && !raw_value().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# raw_value: UNREADABLE\n");
+      }
+    }
+
+    if (has_value().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          value().IsAggregate() || value().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# value: ");
+        value().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# value: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ private:
+  constexpr ::emboss::support::MaybeConstantView</**/ ::std::int32_t>
+  bias() const {
+    return parameters_initialized_
+               ? ::emboss::support::MaybeConstantView</**/ ::std::int32_t>(
+                     bias_)
+               : ::emboss::support::MaybeConstantView</**/ ::std::int32_t>();
+  }
+  constexpr ::emboss::support::Maybe<bool> has_bias() const {
+    return ::emboss::support::Maybe<bool>(parameters_initialized_);
+  }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ raw_value() const;
+  ::emboss::support::Maybe<bool> has_raw_value() const;
+
+ public:
+  class EmbossReservedVirtualValueView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedVirtualValueView(
+        const GenericBiasedValueView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualValueView() = delete;
+    EmbossReservedVirtualValueView(const EmbossReservedVirtualValueView &) = default;
+    EmbossReservedVirtualValueView(EmbossReservedVirtualValueView &&) = default;
+    EmbossReservedVirtualValueView &operator=(const EmbossReservedVirtualValueView &) =
+        default;
+    EmbossReservedVirtualValueView &operator=(EmbossReservedVirtualValueView &&) =
+        default;
+    ~EmbossReservedVirtualValueView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_value().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.raw_value();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = view_.bias();
+      const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_4);
+
+      return emboss_reserved_local_subexpr_5;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericBiasedValueView view_;
+  };
+  EmbossReservedVirtualValueView value() const;
+  ::emboss::support::Maybe<bool> has_value() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  ::std::int32_t bias_;
+  bool parameters_initialized_ = false;
+
+  template <class OtherStorage>
+  friend class GenericBiasedValueView;
+};
+using BiasedValueView =
+    GenericBiasedValueView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using BiasedValueWriter =
+    GenericBiasedValueView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericBiasedValueView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericBiasedValueView<
+    GenericBiasedValueView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericBiasedValueView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeBiasedValueView(::std::int32_t bias,  T &&emboss_reserved_local_arg) {
+  return GenericBiasedValueView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+      ::std::forward</**/::std::int32_t>(bias), ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericBiasedValueView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeBiasedValueView(::std::int32_t bias,  T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericBiasedValueView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+      ::std::forward</**/::std::int32_t>(bias), emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericBiasedValueView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedBiasedValueView(
+    ::std::int32_t bias,  T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericBiasedValueView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+      ::std::forward</**/::std::int32_t>(bias), emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace VirtualFirstFieldWithParam {
+
+}  // namespace VirtualFirstFieldWithParam
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericVirtualFirstFieldWithParamView;
+
+template <class Storage>
+class GenericVirtualFirstFieldWithParamView final {
+ public:
+  GenericVirtualFirstFieldWithParamView() : backing_() {}
+  explicit GenericVirtualFirstFieldWithParamView(
+      ::std::int32_t param,  Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) , param_(param)
+        , parameters_initialized_(true) {}
+
+  template <typename OtherStorage>
+  GenericVirtualFirstFieldWithParamView(
+      const GenericVirtualFirstFieldWithParamView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+        , param_(emboss_reserved_local_other.param_)
+, parameters_initialized_(emboss_reserved_local_other.parameters_initialized_) {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericVirtualFirstFieldWithParamView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericVirtualFirstFieldWithParamView(
+      ::std::int32_t param,  Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) , param_(param)
+        , parameters_initialized_(true) {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericVirtualFirstFieldWithParamView(
+      ::std::int32_t param,  Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) , param_(param)
+        , parameters_initialized_(true) {}
+
+  template <typename OtherStorage>
+  GenericVirtualFirstFieldWithParamView<Storage> &operator=(
+      const GenericVirtualFirstFieldWithParamView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+if (!parameters_initialized_) return false;
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_value().Known()) return false;
+    if (has_value().ValueOrDefault() && !value().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericVirtualFirstFieldWithParamView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_param().Known()) return false;
+    if (!emboss_reserved_local_other.has_param().Known()) return false;
+
+    if (emboss_reserved_local_other.has_param().ValueOrDefault() &&
+        !has_param().ValueOrDefault())
+      return false;
+    if (has_param().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_param().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_param().ValueOrDefault() &&
+        has_param().ValueOrDefault() &&
+        !param().Equals(emboss_reserved_local_other.param()))
+      return false;
+
+
+
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericVirtualFirstFieldWithParamView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_param().ValueOr(false) &&
+        !has_param().ValueOr(false))
+      return false;
+    if (has_param().ValueOr(false) &&
+        !emboss_reserved_local_other.has_param().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_param().ValueOr(false) &&
+        has_param().ValueOr(false) &&
+        !param().UncheckedEquals(emboss_reserved_local_other.param()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericVirtualFirstFieldWithParamView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericVirtualFirstFieldWithParamView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericVirtualFirstFieldWithParamView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "value") {
+        if (!value().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_value().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          value().IsAggregate() || value().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("value: ");
+        value().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !value().IsAggregate() && !value().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# value: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ private:
+  constexpr ::emboss::support::MaybeConstantView</**/ ::std::int32_t>
+  param() const {
+    return parameters_initialized_
+               ? ::emboss::support::MaybeConstantView</**/ ::std::int32_t>(
+                     param_)
+               : ::emboss::support::MaybeConstantView</**/ ::std::int32_t>();
+  }
+  constexpr ::emboss::support::Maybe<bool> has_param() const {
+    return ::emboss::support::Maybe<bool>(parameters_initialized_);
+  }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  auto value() const -> decltype(this->x()) {
+   return has_value().ValueOrDefault() ? x()
+                                          : decltype(this->x())();
+  }
+  ::emboss::support::Maybe<bool> has_value() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  ::std::int32_t param_;
+  bool parameters_initialized_ = false;
+
+  template <class OtherStorage>
+  friend class GenericVirtualFirstFieldWithParamView;
+};
+using VirtualFirstFieldWithParamView =
+    GenericVirtualFirstFieldWithParamView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using VirtualFirstFieldWithParamWriter =
+    GenericVirtualFirstFieldWithParamView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericVirtualFirstFieldWithParamView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericVirtualFirstFieldWithParamView<
+    GenericVirtualFirstFieldWithParamView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericVirtualFirstFieldWithParamView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeVirtualFirstFieldWithParamView(::std::int32_t param,  T &&emboss_reserved_local_arg) {
+  return GenericVirtualFirstFieldWithParamView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+      ::std::forward</**/::std::int32_t>(param), ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericVirtualFirstFieldWithParamView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeVirtualFirstFieldWithParamView(::std::int32_t param,  T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericVirtualFirstFieldWithParamView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+      ::std::forward</**/::std::int32_t>(param), emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericVirtualFirstFieldWithParamView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedVirtualFirstFieldWithParamView(
+    ::std::int32_t param,  T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericVirtualFirstFieldWithParamView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+      ::std::forward</**/::std::int32_t>(param), emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace ConstVirtualFirstFieldWithParam {
+
+}  // namespace ConstVirtualFirstFieldWithParam
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericConstVirtualFirstFieldWithParamView;
+
+template <class Storage>
+class GenericConstVirtualFirstFieldWithParamView final {
+ public:
+  GenericConstVirtualFirstFieldWithParamView() : backing_() {}
+  explicit GenericConstVirtualFirstFieldWithParamView(
+      ::std::int32_t param,  Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) , param_(param)
+        , parameters_initialized_(true) {}
+
+  template <typename OtherStorage>
+  GenericConstVirtualFirstFieldWithParamView(
+      const GenericConstVirtualFirstFieldWithParamView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+        , param_(emboss_reserved_local_other.param_)
+, parameters_initialized_(emboss_reserved_local_other.parameters_initialized_) {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericConstVirtualFirstFieldWithParamView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericConstVirtualFirstFieldWithParamView(
+      ::std::int32_t param,  Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) , param_(param)
+        , parameters_initialized_(true) {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericConstVirtualFirstFieldWithParamView(
+      ::std::int32_t param,  Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) , param_(param)
+        , parameters_initialized_(true) {}
+
+  template <typename OtherStorage>
+  GenericConstVirtualFirstFieldWithParamView<Storage> &operator=(
+      const GenericConstVirtualFirstFieldWithParamView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+if (!parameters_initialized_) return false;
+    if (!has_value().Known()) return false;
+    if (has_value().ValueOrDefault() && !value().Ok()) return false;
+
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericConstVirtualFirstFieldWithParamView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_param().Known()) return false;
+    if (!emboss_reserved_local_other.has_param().Known()) return false;
+
+    if (emboss_reserved_local_other.has_param().ValueOrDefault() &&
+        !has_param().ValueOrDefault())
+      return false;
+    if (has_param().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_param().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_param().ValueOrDefault() &&
+        has_param().ValueOrDefault() &&
+        !param().Equals(emboss_reserved_local_other.param()))
+      return false;
+
+
+
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericConstVirtualFirstFieldWithParamView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_param().ValueOr(false) &&
+        !has_param().ValueOr(false))
+      return false;
+    if (has_param().ValueOr(false) &&
+        !emboss_reserved_local_other.has_param().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_param().ValueOr(false) &&
+        has_param().ValueOr(false) &&
+        !param().UncheckedEquals(emboss_reserved_local_other.param()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericConstVirtualFirstFieldWithParamView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericConstVirtualFirstFieldWithParamView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericConstVirtualFirstFieldWithParamView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_value().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          value().IsAggregate() || value().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# value: ");
+        value().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# value: UNREADABLE\n");
+      }
+    }
+
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ private:
+  constexpr ::emboss::support::MaybeConstantView</**/ ::std::int32_t>
+  param() const {
+    return parameters_initialized_
+               ? ::emboss::support::MaybeConstantView</**/ ::std::int32_t>(
+                     param_)
+               : ::emboss::support::MaybeConstantView</**/ ::std::int32_t>();
+  }
+  constexpr ::emboss::support::Maybe<bool> has_param() const {
+    return ::emboss::support::Maybe<bool>(parameters_initialized_);
+  }
+
+ public:
+  class EmbossReservedVirtualValueView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedVirtualValueView() {}
+    EmbossReservedVirtualValueView(const EmbossReservedVirtualValueView &) = default;
+    EmbossReservedVirtualValueView(EmbossReservedVirtualValueView &&) = default;
+    EmbossReservedVirtualValueView &operator=(const EmbossReservedVirtualValueView &) =
+        default;
+    EmbossReservedVirtualValueView &operator=(EmbossReservedVirtualValueView &&) =
+        default;
+    ~EmbossReservedVirtualValueView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedVirtualValueView value() {
+    return EmbossReservedVirtualValueView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_value() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  ::std::int32_t param_;
+  bool parameters_initialized_ = false;
+
+  template <class OtherStorage>
+  friend class GenericConstVirtualFirstFieldWithParamView;
+};
+using ConstVirtualFirstFieldWithParamView =
+    GenericConstVirtualFirstFieldWithParamView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ConstVirtualFirstFieldWithParamWriter =
+    GenericConstVirtualFirstFieldWithParamView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericConstVirtualFirstFieldWithParamView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericConstVirtualFirstFieldWithParamView<
+    GenericConstVirtualFirstFieldWithParamView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericConstVirtualFirstFieldWithParamView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeConstVirtualFirstFieldWithParamView(::std::int32_t param,  T &&emboss_reserved_local_arg) {
+  return GenericConstVirtualFirstFieldWithParamView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+      ::std::forward</**/::std::int32_t>(param), ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericConstVirtualFirstFieldWithParamView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeConstVirtualFirstFieldWithParamView(::std::int32_t param,  T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericConstVirtualFirstFieldWithParamView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+      ::std::forward</**/::std::int32_t>(param), emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericConstVirtualFirstFieldWithParamView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedConstVirtualFirstFieldWithParamView(
+    ::std::int32_t param,  T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericConstVirtualFirstFieldWithParamView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+      ::std::forward</**/::std::int32_t>(param), emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace SizedArrayOfBiasedValues {
+
+}  // namespace SizedArrayOfBiasedValues
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericSizedArrayOfBiasedValuesView;
+
+template <class Storage>
+class GenericSizedArrayOfBiasedValuesView final {
+ public:
+  GenericSizedArrayOfBiasedValuesView() : backing_() {}
+  explicit GenericSizedArrayOfBiasedValuesView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericSizedArrayOfBiasedValuesView(
+      const GenericSizedArrayOfBiasedValuesView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericSizedArrayOfBiasedValuesView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericSizedArrayOfBiasedValuesView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericSizedArrayOfBiasedValuesView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericSizedArrayOfBiasedValuesView<Storage> &operator=(
+      const GenericSizedArrayOfBiasedValuesView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_element_count().Known()) return false;
+    if (has_element_count().ValueOrDefault() && !element_count().Ok()) return false;
+
+
+    if (!has_bias().Known()) return false;
+    if (has_bias().ValueOrDefault() && !bias().Ok()) return false;
+
+
+    if (!has_values().Known()) return false;
+    if (has_values().ValueOrDefault() && !values().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericSizedArrayOfBiasedValuesView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_element_count().Known()) return false;
+    if (!emboss_reserved_local_other.has_element_count().Known()) return false;
+
+    if (emboss_reserved_local_other.has_element_count().ValueOrDefault() &&
+        !has_element_count().ValueOrDefault())
+      return false;
+    if (has_element_count().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_element_count().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_element_count().ValueOrDefault() &&
+        has_element_count().ValueOrDefault() &&
+        !element_count().Equals(emboss_reserved_local_other.element_count()))
+      return false;
+
+
+
+    if (!has_bias().Known()) return false;
+    if (!emboss_reserved_local_other.has_bias().Known()) return false;
+
+    if (emboss_reserved_local_other.has_bias().ValueOrDefault() &&
+        !has_bias().ValueOrDefault())
+      return false;
+    if (has_bias().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_bias().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_bias().ValueOrDefault() &&
+        has_bias().ValueOrDefault() &&
+        !bias().Equals(emboss_reserved_local_other.bias()))
+      return false;
+
+
+
+    if (!has_values().Known()) return false;
+    if (!emboss_reserved_local_other.has_values().Known()) return false;
+
+    if (emboss_reserved_local_other.has_values().ValueOrDefault() &&
+        !has_values().ValueOrDefault())
+      return false;
+    if (has_values().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_values().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_values().ValueOrDefault() &&
+        has_values().ValueOrDefault() &&
+        !values().Equals(emboss_reserved_local_other.values()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericSizedArrayOfBiasedValuesView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_element_count().ValueOr(false) &&
+        !has_element_count().ValueOr(false))
+      return false;
+    if (has_element_count().ValueOr(false) &&
+        !emboss_reserved_local_other.has_element_count().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_element_count().ValueOr(false) &&
+        has_element_count().ValueOr(false) &&
+        !element_count().UncheckedEquals(emboss_reserved_local_other.element_count()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_bias().ValueOr(false) &&
+        !has_bias().ValueOr(false))
+      return false;
+    if (has_bias().ValueOr(false) &&
+        !emboss_reserved_local_other.has_bias().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_bias().ValueOr(false) &&
+        has_bias().ValueOr(false) &&
+        !bias().UncheckedEquals(emboss_reserved_local_other.bias()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_values().ValueOr(false) &&
+        !has_values().ValueOr(false))
+      return false;
+    if (has_values().ValueOr(false) &&
+        !emboss_reserved_local_other.has_values().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_values().ValueOr(false) &&
+        has_values().ValueOr(false) &&
+        !values().UncheckedEquals(emboss_reserved_local_other.values()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericSizedArrayOfBiasedValuesView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericSizedArrayOfBiasedValuesView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericSizedArrayOfBiasedValuesView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "element_count") {
+        if (!element_count().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "bias") {
+        if (!bias().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "values") {
+        if (!values().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_element_count().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          element_count().IsAggregate() || element_count().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("element_count: ");
+        element_count().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !element_count().IsAggregate() && !element_count().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# element_count: UNREADABLE\n");
+      }
+    }
+
+    if (has_bias().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          bias().IsAggregate() || bias().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("bias: ");
+        bias().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !bias().IsAggregate() && !bias().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# bias: UNREADABLE\n");
+      }
+    }
+
+    if (has_values().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          values().IsAggregate() || values().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("values: ");
+        values().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !values().IsAggregate() && !values().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# values: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ element_count() const;
+  ::emboss::support::Maybe<bool> has_element_count() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ bias() const;
+  ::emboss::support::Maybe<bool> has_bias() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericBiasedValueView<typename Storage::template OffsetStorageType</**/0, 2>::template OffsetStorageType</**/1, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 2>, 1,
+    8 , ::std::int32_t>
+
+ values() const;
+  ::emboss::support::Maybe<bool> has_values() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericSizedArrayOfBiasedValuesView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.element_count();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), emboss_reserved_local_subexpr_2);
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), emboss_reserved_local_subexpr_4);
+
+      return emboss_reserved_local_subexpr_5;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericSizedArrayOfBiasedValuesView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericSizedArrayOfBiasedValuesView;
+};
+using SizedArrayOfBiasedValuesView =
+    GenericSizedArrayOfBiasedValuesView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using SizedArrayOfBiasedValuesWriter =
+    GenericSizedArrayOfBiasedValuesView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericSizedArrayOfBiasedValuesView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericSizedArrayOfBiasedValuesView<
+    GenericSizedArrayOfBiasedValuesView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericSizedArrayOfBiasedValuesView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeSizedArrayOfBiasedValuesView( T &&emboss_reserved_local_arg) {
+  return GenericSizedArrayOfBiasedValuesView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericSizedArrayOfBiasedValuesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeSizedArrayOfBiasedValuesView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericSizedArrayOfBiasedValuesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericSizedArrayOfBiasedValuesView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedSizedArrayOfBiasedValuesView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericSizedArrayOfBiasedValuesView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace MultiVersion {
+
+}  // namespace MultiVersion
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::MessageId,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericMultiVersionView<Storage>::message_id()
+    const {
+
+  if ( has_message_id().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::MessageId,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::MessageId,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericMultiVersionView<Storage>::has_message_id() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericAxesView<typename Storage::template OffsetStorageType</**/0, 1>>
+
+ GenericMultiVersionView<Storage>::axes()
+    const {
+  const auto emboss_reserved_local_subexpr_1 = product();
+  const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::emboss::test::Product>(static_cast</**/::emboss::test::Product>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::Product>());
+  const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Equal</**/::emboss::test::Product, bool, ::emboss::test::Product, ::emboss::test::Product>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::emboss::test::Product>(static_cast</**/::emboss::test::Product>(23)));
+  const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)));
+
+  if (emboss_reserved_local_subexpr_4.Known() &&  has_axes().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(12LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericAxesView<typename Storage::template OffsetStorageType</**/0, 1>>
+
+(
+                emboss_reserved_local_subexpr_4.ValueOrDefault(),  backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericAxesView<typename Storage::template OffsetStorageType</**/0, 1>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericMultiVersionView<Storage>::has_axes() const {
+  return ::emboss::support::Equal</**/::emboss::test::MessageId, bool, ::emboss::test::MessageId, ::emboss::test::MessageId>((message_id().Ok()    ? ::emboss::support::Maybe</**/::emboss::test::MessageId>(static_cast</**/::emboss::test::MessageId>(message_id().UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::MessageId>()), ::emboss::support::Maybe</**/::emboss::test::MessageId>(static_cast</**/::emboss::test::MessageId>(0)));
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericConfigView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 32>>
+
+ GenericMultiVersionView<Storage>::config()
+    const {
+
+  if ( has_config().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericConfigView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericConfigView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericMultiVersionView<Storage>::has_config() const {
+  return ::emboss::support::Equal</**/::emboss::test::MessageId, bool, ::emboss::test::MessageId, ::emboss::test::MessageId>((message_id().Ok()    ? ::emboss::support::Maybe</**/::emboss::test::MessageId>(static_cast</**/::emboss::test::MessageId>(message_id().UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::MessageId>()), ::emboss::support::Maybe</**/::emboss::test::MessageId>(static_cast</**/::emboss::test::MessageId>(1)));
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericConfigVXView<typename Storage::template OffsetStorageType</**/0, 1>>
+
+ GenericMultiVersionView<Storage>::config_vx()
+    const {
+
+  if ( has_config_vx().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericConfigVXView<typename Storage::template OffsetStorageType</**/0, 1>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericConfigVXView<typename Storage::template OffsetStorageType</**/0, 1>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericMultiVersionView<Storage>::has_config_vx() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Equal</**/::emboss::test::Product, bool, ::emboss::test::Product, ::emboss::test::Product>((product().Ok()    ? ::emboss::support::Maybe</**/::emboss::test::Product>(static_cast</**/::emboss::test::Product>(product().UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::Product>()), ::emboss::support::Maybe</**/::emboss::test::Product>(static_cast</**/::emboss::test::Product>(23))), ::emboss::support::Equal</**/::emboss::test::MessageId, bool, ::emboss::test::MessageId, ::emboss::test::MessageId>((message_id().Ok()    ? ::emboss::support::Maybe</**/::emboss::test::MessageId>(static_cast</**/::emboss::test::MessageId>(message_id().UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::MessageId>()), ::emboss::support::Maybe</**/::emboss::test::MessageId>(static_cast</**/::emboss::test::MessageId>(1))));
+}
+
+
+template <class Storage>
+inline typename GenericMultiVersionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericMultiVersionView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericMultiVersionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericMultiVersionView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace MultiVersion {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(13LL)).ValueOrDefault();
+}
+}  // namespace MultiVersion
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericMultiVersionView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return MultiVersion::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericMultiVersionView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return MultiVersion::MaxSizeInBytes();
+}
+
+namespace MultiVersion {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace MultiVersion
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericMultiVersionView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return MultiVersion::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericMultiVersionView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return MultiVersion::MinSizeInBytes();
+}
+namespace Axes {
+
+}  // namespace Axes
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericAxisView<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/4, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 4,
+    8 , ::emboss::test::AxisType>
+
+ GenericAxesView<Storage>::values()
+    const {
+
+  if (::emboss::support::Maybe</**/::emboss::test::AxisType>(static_cast</**/::emboss::test::AxisType>(-1)).Known() &&  has_values().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = axes();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Product</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)));
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_3;
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericAxisView<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/4, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 4,
+    8 , ::emboss::test::AxisType>
+
+(
+                ::emboss::support::Maybe</**/::emboss::test::AxisType>(static_cast</**/::emboss::test::AxisType>(-1)).ValueOrDefault(),  backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericAxisView<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/4, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 4,
+    8 , ::emboss::test::AxisType>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAxesView<Storage>::has_values() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericAxisView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericAxesView<Storage>::x()
+    const {
+
+  if (::emboss::support::Maybe</**/::emboss::test::AxisType>(static_cast</**/::emboss::test::AxisType>(1)).Known() &&  has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericAxisView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                ::emboss::support::Maybe</**/::emboss::test::AxisType>(static_cast</**/::emboss::test::AxisType>(1)).ValueOrDefault(),  backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericAxisView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAxesView<Storage>::has_x() const {
+  return ::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((axes().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(axes().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericAxisView<typename Storage::template OffsetStorageType</**/0, 4>>
+
+ GenericAxesView<Storage>::y()
+    const {
+
+  if (::emboss::support::Maybe</**/::emboss::test::AxisType>(static_cast</**/::emboss::test::AxisType>(2)).Known() &&  has_y().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericAxisView<typename Storage::template OffsetStorageType</**/0, 4>>
+
+(
+                ::emboss::support::Maybe</**/::emboss::test::AxisType>(static_cast</**/::emboss::test::AxisType>(2)).ValueOrDefault(),  backing_
+                        .template GetOffsetStorage<0,
+                                                   4>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericAxisView<typename Storage::template OffsetStorageType</**/0, 4>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAxesView<Storage>::has_y() const {
+  return ::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((axes().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(axes().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericAxisView<typename Storage::template OffsetStorageType</**/0, 8>>
+
+ GenericAxesView<Storage>::z()
+    const {
+
+  if (::emboss::support::Maybe</**/::emboss::test::AxisType>(static_cast</**/::emboss::test::AxisType>(3)).Known() &&  has_z().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericAxisView<typename Storage::template OffsetStorageType</**/0, 8>>
+
+(
+                ::emboss::support::Maybe</**/::emboss::test::AxisType>(static_cast</**/::emboss::test::AxisType>(3)).ValueOrDefault(),  backing_
+                        .template GetOffsetStorage<0,
+                                                   8>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericAxisView<typename Storage::template OffsetStorageType</**/0, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAxesView<Storage>::has_z() const {
+  return ::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((axes().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(axes().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)));
+}
+
+
+template <class Storage>
+inline typename GenericAxesView<Storage>::EmbossReservedVirtualAxisCountPlusOneView
+GenericAxesView<Storage>::axis_count_plus_one() const {
+  return
+      typename GenericAxesView<Storage>::EmbossReservedVirtualAxisCountPlusOneView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAxesView<Storage>::has_axis_count_plus_one() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericAxesView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericAxesView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericAxesView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAxesView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Axes {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(60LL)).ValueOrDefault();
+}
+}  // namespace Axes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAxesView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Axes::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAxesView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Axes::MaxSizeInBytes();
+}
+
+namespace Axes {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)).ValueOrDefault();
+}
+}  // namespace Axes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAxesView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Axes::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAxesView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Axes::MinSizeInBytes();
+}
+namespace AxisPair {
+
+}  // namespace AxisPair
+
+
+template <class Storage>
+inline typename GenericAxisPairView<Storage>::EmbossReservedVirtualAxisTypeAView
+GenericAxisPairView<Storage>::axis_type_a() const {
+  return
+      typename GenericAxisPairView<Storage>::EmbossReservedVirtualAxisTypeAView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAxisPairView<Storage>::has_axis_type_a() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericAxisView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericAxisPairView<Storage>::axis_a()
+    const {
+  const auto emboss_reserved_local_subexpr_1 = axis_type_a();
+  const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::emboss::test::AxisType>(static_cast</**/::emboss::test::AxisType>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::AxisType>());
+
+  if (emboss_reserved_local_subexpr_2.Known() &&  has_axis_a().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericAxisView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                emboss_reserved_local_subexpr_2.ValueOrDefault(),  backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericAxisView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAxisPairView<Storage>::has_axis_a() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericAxisPairView<Storage>::EmbossReservedVirtualAxisTypeBView
+GenericAxisPairView<Storage>::axis_type_b() const {
+  return
+      typename GenericAxisPairView<Storage>::EmbossReservedVirtualAxisTypeBView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAxisPairView<Storage>::has_axis_type_b() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericAxisView<typename Storage::template OffsetStorageType</**/0, 4>>
+
+ GenericAxisPairView<Storage>::axis_b()
+    const {
+  const auto emboss_reserved_local_subexpr_1 = axis_type_b();
+  const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::emboss::test::AxisType>(static_cast</**/::emboss::test::AxisType>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::AxisType>());
+
+  if (emboss_reserved_local_subexpr_2.Known() &&  has_axis_b().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericAxisView<typename Storage::template OffsetStorageType</**/0, 4>>
+
+(
+                emboss_reserved_local_subexpr_2.ValueOrDefault(),  backing_
+                        .template GetOffsetStorage<0,
+                                                   4>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericAxisView<typename Storage::template OffsetStorageType</**/0, 4>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAxisPairView<Storage>::has_axis_b() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace AxisPair {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace AxisPair
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAxisPairView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return AxisPair::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAxisPairView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return AxisPair::IntrinsicSizeInBytes();
+}
+
+namespace AxisPair {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace AxisPair
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAxisPairView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return AxisPair::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAxisPairView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return AxisPair::MaxSizeInBytes();
+}
+
+namespace AxisPair {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace AxisPair
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAxisPairView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return AxisPair::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAxisPairView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return AxisPair::MinSizeInBytes();
+}
+namespace AxesEnvelope {
+
+}  // namespace AxesEnvelope
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericAxesEnvelopeView<Storage>::axis_count()
+    const {
+
+  if ( has_axis_count().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAxesEnvelopeView<Storage>::has_axis_count() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericAxesView<typename Storage::template OffsetStorageType</**/0, 1>>
+
+ GenericAxesEnvelopeView<Storage>::axes()
+    const {
+  const auto emboss_reserved_local_subexpr_1 = axis_count();
+  const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+
+  if (emboss_reserved_local_subexpr_2.Known() &&  has_axes().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Product</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)));
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_3;
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericAxesView<typename Storage::template OffsetStorageType</**/0, 1>>
+
+(
+                emboss_reserved_local_subexpr_2.ValueOrDefault(),  backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericAxesView<typename Storage::template OffsetStorageType</**/0, 1>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAxesEnvelopeView<Storage>::has_axes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericAxesEnvelopeView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericAxesEnvelopeView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericAxesEnvelopeView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAxesEnvelopeView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace AxesEnvelope {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1021LL)).ValueOrDefault();
+}
+}  // namespace AxesEnvelope
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAxesEnvelopeView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return AxesEnvelope::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAxesEnvelopeView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return AxesEnvelope::MaxSizeInBytes();
+}
+
+namespace AxesEnvelope {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace AxesEnvelope
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAxesEnvelopeView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return AxesEnvelope::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAxesEnvelopeView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return AxesEnvelope::MinSizeInBytes();
+}
+namespace Axis {
+
+}  // namespace Axis
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ GenericAxisView<Storage>::value()
+    const {
+
+  if ( has_value().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAxisView<Storage>::has_value() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericAxisView<Storage>::EmbossReservedVirtualAxisTypeView
+GenericAxisView<Storage>::axis_type() const {
+  return
+      typename GenericAxisView<Storage>::EmbossReservedVirtualAxisTypeView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAxisView<Storage>::has_axis_type() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ GenericAxisView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAxisView<Storage>::has_x() const {
+  return ::emboss::support::Equal</**/::emboss::test::AxisType, bool, ::emboss::test::AxisType, ::emboss::test::AxisType>((axis_type().Ok()    ? ::emboss::support::Maybe</**/::emboss::test::AxisType>(static_cast</**/::emboss::test::AxisType>(axis_type().UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::AxisType>()), ::emboss::support::Maybe</**/::emboss::test::AxisType>(static_cast</**/::emboss::test::AxisType>(1)));
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ GenericAxisView<Storage>::y()
+    const {
+
+  if ( has_y().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAxisView<Storage>::has_y() const {
+  return ::emboss::support::Equal</**/::emboss::test::AxisType, bool, ::emboss::test::AxisType, ::emboss::test::AxisType>((axis_type().Ok()    ? ::emboss::support::Maybe</**/::emboss::test::AxisType>(static_cast</**/::emboss::test::AxisType>(axis_type().UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::AxisType>()), ::emboss::support::Maybe</**/::emboss::test::AxisType>(static_cast</**/::emboss::test::AxisType>(2)));
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ GenericAxisView<Storage>::z()
+    const {
+
+  if ( has_z().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAxisView<Storage>::has_z() const {
+  return ::emboss::support::Equal</**/::emboss::test::AxisType, bool, ::emboss::test::AxisType, ::emboss::test::AxisType>((axis_type().Ok()    ? ::emboss::support::Maybe</**/::emboss::test::AxisType>(static_cast</**/::emboss::test::AxisType>(axis_type().UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::AxisType>()), ::emboss::support::Maybe</**/::emboss::test::AxisType>(static_cast</**/::emboss::test::AxisType>(3)));
+}
+
+
+namespace Axis {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace Axis
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAxisView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Axis::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAxisView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Axis::IntrinsicSizeInBytes();
+}
+
+namespace Axis {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace Axis
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAxisView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Axis::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAxisView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Axis::MaxSizeInBytes();
+}
+
+namespace Axis {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace Axis
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAxisView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Axis::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAxisView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Axis::MinSizeInBytes();
+}
+namespace Config {
+
+}  // namespace Config
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 31>>
+
+ GenericConfigView<Storage>::power()
+    const {
+
+  if ( has_power().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(31LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 31>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   31>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 31>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConfigView<Storage>::has_power() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Config {
+inline constexpr ::std::int32_t IntrinsicSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(32LL)).ValueOrDefault();
+}
+}  // namespace Config
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConfigView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
+  return Config::IntrinsicSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConfigView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
+  return Config::IntrinsicSizeInBits();
+}
+
+namespace Config {
+inline constexpr ::std::int32_t MaxSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(32LL)).ValueOrDefault();
+}
+}  // namespace Config
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConfigView<Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
+  return Config::MaxSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConfigView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
+  return Config::MaxSizeInBits();
+}
+
+namespace Config {
+inline constexpr ::std::int32_t MinSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(32LL)).ValueOrDefault();
+}
+}  // namespace Config
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConfigView<Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
+  return Config::MinSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConfigView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
+  return Config::MinSizeInBits();
+}
+namespace ConfigVX {
+namespace EmbossReservedAnonymousField1 {
+
+}  // namespace EmbossReservedAnonymousField1
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 31>>
+
+ GenericEmbossReservedAnonymousField1View<Storage>::power()
+    const {
+
+  if ( has_power().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(31LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 31>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   31>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 31>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField1View<Storage>::has_power() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace EmbossReservedAnonymousField1 {
+inline constexpr ::std::int32_t IntrinsicSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(32LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField1
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField1::IntrinsicSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField1::IntrinsicSizeInBits();
+}
+
+namespace EmbossReservedAnonymousField1 {
+inline constexpr ::std::int32_t MaxSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(32LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField1
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField1::MaxSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField1::MaxSizeInBits();
+}
+
+namespace EmbossReservedAnonymousField1 {
+inline constexpr ::std::int32_t MinSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(32LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField1
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField1::MinSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField1::MinSizeInBits();
+}
+
+}  // namespace ConfigVX
+
+
+template <class Storage>
+inline typename ::emboss::test::ConfigVX::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ GenericConfigVXView<Storage>::emboss_reserved_anonymous_field_1()
+    const {
+
+  if ( has_emboss_reserved_anonymous_field_1().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::ConfigVX::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::ConfigVX::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConfigVXView<Storage>::has_emboss_reserved_anonymous_field_1() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConfigVXView<Storage>::has_power() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+ GenericConfigVXView<Storage>::gain()
+    const {
+
+  if ( has_gain().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   4>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConfigVXView<Storage>::has_gain() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace ConfigVX {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace ConfigVX
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConfigVXView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return ConfigVX::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConfigVXView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return ConfigVX::IntrinsicSizeInBytes();
+}
+
+namespace ConfigVX {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace ConfigVX
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConfigVXView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return ConfigVX::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConfigVXView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return ConfigVX::MaxSizeInBytes();
+}
+
+namespace ConfigVX {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace ConfigVX
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConfigVXView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return ConfigVX::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConfigVXView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return ConfigVX::MinSizeInBytes();
+}
+namespace StructWithUnusedParameter {
+
+}  // namespace StructWithUnusedParameter
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericStructWithUnusedParameterView<Storage>::y()
+    const {
+
+  if ( has_y().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructWithUnusedParameterView<Storage>::has_y() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace StructWithUnusedParameter {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace StructWithUnusedParameter
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructWithUnusedParameterView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return StructWithUnusedParameter::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructWithUnusedParameterView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return StructWithUnusedParameter::IntrinsicSizeInBytes();
+}
+
+namespace StructWithUnusedParameter {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace StructWithUnusedParameter
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructWithUnusedParameterView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return StructWithUnusedParameter::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructWithUnusedParameterView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return StructWithUnusedParameter::MaxSizeInBytes();
+}
+
+namespace StructWithUnusedParameter {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace StructWithUnusedParameter
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructWithUnusedParameterView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return StructWithUnusedParameter::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructWithUnusedParameterView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return StructWithUnusedParameter::MinSizeInBytes();
+}
+namespace StructContainingStructWithUnusedParameter {
+
+}  // namespace StructContainingStructWithUnusedParameter
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericStructContainingStructWithUnusedParameterView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructContainingStructWithUnusedParameterView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericStructWithUnusedParameterView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericStructContainingStructWithUnusedParameterView<Storage>::swup()
+    const {
+  const auto emboss_reserved_local_subexpr_1 = x();
+  const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+
+  if (emboss_reserved_local_subexpr_2.Known() &&  has_swup().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericStructWithUnusedParameterView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                emboss_reserved_local_subexpr_2.ValueOrDefault(),  backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericStructWithUnusedParameterView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructContainingStructWithUnusedParameterView<Storage>::has_swup() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace StructContainingStructWithUnusedParameter {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace StructContainingStructWithUnusedParameter
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructContainingStructWithUnusedParameterView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return StructContainingStructWithUnusedParameter::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructContainingStructWithUnusedParameterView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return StructContainingStructWithUnusedParameter::IntrinsicSizeInBytes();
+}
+
+namespace StructContainingStructWithUnusedParameter {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace StructContainingStructWithUnusedParameter
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructContainingStructWithUnusedParameterView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return StructContainingStructWithUnusedParameter::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructContainingStructWithUnusedParameterView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return StructContainingStructWithUnusedParameter::MaxSizeInBytes();
+}
+
+namespace StructContainingStructWithUnusedParameter {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace StructContainingStructWithUnusedParameter
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructContainingStructWithUnusedParameterView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return StructContainingStructWithUnusedParameter::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructContainingStructWithUnusedParameterView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return StructContainingStructWithUnusedParameter::MinSizeInBytes();
+}
+namespace BiasedValue {
+
+}  // namespace BiasedValue
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericBiasedValueView<Storage>::raw_value()
+    const {
+
+  if ( has_raw_value().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBiasedValueView<Storage>::has_raw_value() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericBiasedValueView<Storage>::EmbossReservedVirtualValueView
+GenericBiasedValueView<Storage>::value() const {
+  return
+      typename GenericBiasedValueView<Storage>::EmbossReservedVirtualValueView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBiasedValueView<Storage>::has_value() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace BiasedValue {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace BiasedValue
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBiasedValueView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return BiasedValue::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBiasedValueView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return BiasedValue::IntrinsicSizeInBytes();
+}
+
+namespace BiasedValue {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace BiasedValue
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBiasedValueView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return BiasedValue::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBiasedValueView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return BiasedValue::MaxSizeInBytes();
+}
+
+namespace BiasedValue {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace BiasedValue
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBiasedValueView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return BiasedValue::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBiasedValueView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return BiasedValue::MinSizeInBytes();
+}
+namespace VirtualFirstFieldWithParam {
+
+}  // namespace VirtualFirstFieldWithParam
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericVirtualFirstFieldWithParamView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericVirtualFirstFieldWithParamView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericVirtualFirstFieldWithParamView<Storage>::has_value() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace VirtualFirstFieldWithParam {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace VirtualFirstFieldWithParam
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericVirtualFirstFieldWithParamView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return VirtualFirstFieldWithParam::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericVirtualFirstFieldWithParamView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return VirtualFirstFieldWithParam::IntrinsicSizeInBytes();
+}
+
+namespace VirtualFirstFieldWithParam {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace VirtualFirstFieldWithParam
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericVirtualFirstFieldWithParamView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return VirtualFirstFieldWithParam::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericVirtualFirstFieldWithParamView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return VirtualFirstFieldWithParam::MaxSizeInBytes();
+}
+
+namespace VirtualFirstFieldWithParam {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace VirtualFirstFieldWithParam
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericVirtualFirstFieldWithParamView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return VirtualFirstFieldWithParam::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericVirtualFirstFieldWithParamView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return VirtualFirstFieldWithParam::MinSizeInBytes();
+}
+namespace ConstVirtualFirstFieldWithParam {
+
+}  // namespace ConstVirtualFirstFieldWithParam
+
+
+namespace ConstVirtualFirstFieldWithParam {
+inline constexpr ::std::int32_t value() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)).ValueOrDefault();
+}
+}  // namespace ConstVirtualFirstFieldWithParam
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConstVirtualFirstFieldWithParamView<Storage>::EmbossReservedVirtualValueView::Read() {
+  return ConstVirtualFirstFieldWithParam::value();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConstVirtualFirstFieldWithParamView<
+    Storage>::EmbossReservedVirtualValueView::UncheckedRead() {
+  return ConstVirtualFirstFieldWithParam::value();
+}
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericConstVirtualFirstFieldWithParamView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericConstVirtualFirstFieldWithParamView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace ConstVirtualFirstFieldWithParam {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace ConstVirtualFirstFieldWithParam
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConstVirtualFirstFieldWithParamView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return ConstVirtualFirstFieldWithParam::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConstVirtualFirstFieldWithParamView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return ConstVirtualFirstFieldWithParam::IntrinsicSizeInBytes();
+}
+
+namespace ConstVirtualFirstFieldWithParam {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace ConstVirtualFirstFieldWithParam
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConstVirtualFirstFieldWithParamView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return ConstVirtualFirstFieldWithParam::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConstVirtualFirstFieldWithParamView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return ConstVirtualFirstFieldWithParam::MaxSizeInBytes();
+}
+
+namespace ConstVirtualFirstFieldWithParam {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace ConstVirtualFirstFieldWithParam
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConstVirtualFirstFieldWithParamView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return ConstVirtualFirstFieldWithParam::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericConstVirtualFirstFieldWithParamView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return ConstVirtualFirstFieldWithParam::MinSizeInBytes();
+}
+namespace SizedArrayOfBiasedValues {
+
+}  // namespace SizedArrayOfBiasedValues
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericSizedArrayOfBiasedValuesView<Storage>::element_count()
+    const {
+
+  if ( has_element_count().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizedArrayOfBiasedValuesView<Storage>::has_element_count() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericSizedArrayOfBiasedValuesView<Storage>::bias()
+    const {
+
+  if ( has_bias().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizedArrayOfBiasedValuesView<Storage>::has_bias() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericBiasedValueView<typename Storage::template OffsetStorageType</**/0, 2>::template OffsetStorageType</**/1, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 2>, 1,
+    8 , ::std::int32_t>
+
+ GenericSizedArrayOfBiasedValuesView<Storage>::values()
+    const {
+  const auto emboss_reserved_local_subexpr_1 = bias();
+  const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+
+  if (emboss_reserved_local_subexpr_2.Known() &&  has_values().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_3 = element_count();
+    const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_4;
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericBiasedValueView<typename Storage::template OffsetStorageType</**/0, 2>::template OffsetStorageType</**/1, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 2>, 1,
+    8 , ::std::int32_t>
+
+(
+                emboss_reserved_local_subexpr_2.ValueOrDefault(),  backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::test::GenericBiasedValueView<typename Storage::template OffsetStorageType</**/0, 2>::template OffsetStorageType</**/1, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 2>, 1,
+    8 , ::std::int32_t>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizedArrayOfBiasedValuesView<Storage>::has_values() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericSizedArrayOfBiasedValuesView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericSizedArrayOfBiasedValuesView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericSizedArrayOfBiasedValuesView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizedArrayOfBiasedValuesView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace SizedArrayOfBiasedValues {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(257LL)).ValueOrDefault();
+}
+}  // namespace SizedArrayOfBiasedValues
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizedArrayOfBiasedValuesView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return SizedArrayOfBiasedValues::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizedArrayOfBiasedValuesView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return SizedArrayOfBiasedValues::MaxSizeInBytes();
+}
+
+namespace SizedArrayOfBiasedValues {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace SizedArrayOfBiasedValues
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizedArrayOfBiasedValuesView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return SizedArrayOfBiasedValues::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizedArrayOfBiasedValuesView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return SizedArrayOfBiasedValues::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_PARAMETERS_EMB_H_
+
diff --git a/testdata/golden_cpp/requires.emb.h b/testdata/golden_cpp/requires.emb.h
new file mode 100644
index 0000000..500813b
--- /dev/null
+++ b/testdata/golden_cpp/requires.emb.h
@@ -0,0 +1,7045 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_REQUIRES_EMB_H_
+#define TESTDATA_REQUIRES_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace RequiresIntegers {
+
+}  // namespace RequiresIntegers
+
+
+template <class Storage>
+class GenericRequiresIntegersView;
+
+namespace RequiresBools {
+namespace EmbossReservedAnonymousField2 {
+
+}  // namespace EmbossReservedAnonymousField2
+
+
+template <class Storage>
+class GenericEmbossReservedAnonymousField2View;
+
+
+}  // namespace RequiresBools
+
+
+template <class Storage>
+class GenericRequiresBoolsView;
+
+namespace RequiresEnums {
+enum class Enum : ::std::uint64_t;
+
+
+}  // namespace RequiresEnums
+
+
+template <class Storage>
+class GenericRequiresEnumsView;
+
+namespace RequiresWithOptionalFields {
+namespace EmbossReservedAnonymousField1 {
+
+}  // namespace EmbossReservedAnonymousField1
+
+
+template <class Storage>
+class GenericEmbossReservedAnonymousField1View;
+
+
+}  // namespace RequiresWithOptionalFields
+
+
+template <class Storage>
+class GenericRequiresWithOptionalFieldsView;
+
+namespace RequiresInArrayElements {
+namespace Element {
+
+}  // namespace Element
+
+
+template <class Storage>
+class GenericElementView;
+
+
+}  // namespace RequiresInArrayElements
+
+
+template <class Storage>
+class GenericRequiresInArrayElementsView;
+
+
+namespace RequiresIntegers {
+struct EmbossReservedValidatorForZeroThroughNine {
+  template <typename ValueType>
+  static constexpr bool ValueIsOk(ValueType emboss_reserved_local_value) {
+    return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+           (::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value)), ::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(9LL))))).ValueOrDefault();
+  }
+};
+
+
+}  // namespace RequiresIntegers
+
+
+
+namespace RequiresIntegers {
+struct EmbossReservedValidatorForTenThroughTwenty {
+  template <typename ValueType>
+  static constexpr bool ValueIsOk(ValueType emboss_reserved_local_value) {
+    return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+           (::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)), ::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value)), ::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(20LL))))).ValueOrDefault();
+  }
+};
+
+
+}  // namespace RequiresIntegers
+
+
+
+namespace RequiresIntegers {
+struct EmbossReservedValidatorForDisjoint {
+  template <typename ValueType>
+  static constexpr bool ValueIsOk(ValueType emboss_reserved_local_value) {
+    return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+           (::emboss::support::Or</**/bool, bool, bool, bool>(::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value)), ::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)))), ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(15LL)), ::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value)), ::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(20LL)))))).ValueOrDefault();
+  }
+};
+
+
+}  // namespace RequiresIntegers
+
+
+
+
+
+
+
+
+namespace RequiresIntegers {
+
+}  // namespace RequiresIntegers
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericRequiresIntegersView;
+
+template <class Storage>
+class GenericRequiresIntegersView final {
+ public:
+  GenericRequiresIntegersView() : backing_() {}
+  explicit GenericRequiresIntegersView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericRequiresIntegersView(
+      const GenericRequiresIntegersView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericRequiresIntegersView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericRequiresIntegersView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericRequiresIntegersView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericRequiresIntegersView<Storage> &operator=(
+      const GenericRequiresIntegersView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_zero_through_nine().Known()) return false;
+    if (has_zero_through_nine().ValueOrDefault() && !zero_through_nine().Ok()) return false;
+
+
+    if (!has_ten_through_twenty().Known()) return false;
+    if (has_ten_through_twenty().ValueOrDefault() && !ten_through_twenty().Ok()) return false;
+
+
+    if (!has_disjoint().Known()) return false;
+    if (has_disjoint().ValueOrDefault() && !disjoint().Ok()) return false;
+
+
+    if (!has_ztn_plus_ttt().Known()) return false;
+    if (has_ztn_plus_ttt().ValueOrDefault() && !ztn_plus_ttt().Ok()) return false;
+
+
+    if (!has_alias_of_zero_through_nine().Known()) return false;
+    if (has_alias_of_zero_through_nine().ValueOrDefault() && !alias_of_zero_through_nine().Ok()) return false;
+
+
+    if (!has_zero_through_nine_plus_five().Known()) return false;
+    if (has_zero_through_nine_plus_five().ValueOrDefault() && !zero_through_nine_plus_five().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+    if (!(::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((zero_through_nine().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(zero_through_nine().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>((ten_through_twenty().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(ten_through_twenty().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL))))).ValueOr(false))
+      return false;
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericRequiresIntegersView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_zero_through_nine().Known()) return false;
+    if (!emboss_reserved_local_other.has_zero_through_nine().Known()) return false;
+
+    if (emboss_reserved_local_other.has_zero_through_nine().ValueOrDefault() &&
+        !has_zero_through_nine().ValueOrDefault())
+      return false;
+    if (has_zero_through_nine().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_zero_through_nine().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_zero_through_nine().ValueOrDefault() &&
+        has_zero_through_nine().ValueOrDefault() &&
+        !zero_through_nine().Equals(emboss_reserved_local_other.zero_through_nine()))
+      return false;
+
+
+
+    if (!has_ten_through_twenty().Known()) return false;
+    if (!emboss_reserved_local_other.has_ten_through_twenty().Known()) return false;
+
+    if (emboss_reserved_local_other.has_ten_through_twenty().ValueOrDefault() &&
+        !has_ten_through_twenty().ValueOrDefault())
+      return false;
+    if (has_ten_through_twenty().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_ten_through_twenty().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_ten_through_twenty().ValueOrDefault() &&
+        has_ten_through_twenty().ValueOrDefault() &&
+        !ten_through_twenty().Equals(emboss_reserved_local_other.ten_through_twenty()))
+      return false;
+
+
+
+    if (!has_disjoint().Known()) return false;
+    if (!emboss_reserved_local_other.has_disjoint().Known()) return false;
+
+    if (emboss_reserved_local_other.has_disjoint().ValueOrDefault() &&
+        !has_disjoint().ValueOrDefault())
+      return false;
+    if (has_disjoint().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_disjoint().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_disjoint().ValueOrDefault() &&
+        has_disjoint().ValueOrDefault() &&
+        !disjoint().Equals(emboss_reserved_local_other.disjoint()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericRequiresIntegersView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_zero_through_nine().ValueOr(false) &&
+        !has_zero_through_nine().ValueOr(false))
+      return false;
+    if (has_zero_through_nine().ValueOr(false) &&
+        !emboss_reserved_local_other.has_zero_through_nine().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_zero_through_nine().ValueOr(false) &&
+        has_zero_through_nine().ValueOr(false) &&
+        !zero_through_nine().UncheckedEquals(emboss_reserved_local_other.zero_through_nine()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_ten_through_twenty().ValueOr(false) &&
+        !has_ten_through_twenty().ValueOr(false))
+      return false;
+    if (has_ten_through_twenty().ValueOr(false) &&
+        !emboss_reserved_local_other.has_ten_through_twenty().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_ten_through_twenty().ValueOr(false) &&
+        has_ten_through_twenty().ValueOr(false) &&
+        !ten_through_twenty().UncheckedEquals(emboss_reserved_local_other.ten_through_twenty()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_disjoint().ValueOr(false) &&
+        !has_disjoint().ValueOr(false))
+      return false;
+    if (has_disjoint().ValueOr(false) &&
+        !emboss_reserved_local_other.has_disjoint().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_disjoint().ValueOr(false) &&
+        has_disjoint().ValueOr(false) &&
+        !disjoint().UncheckedEquals(emboss_reserved_local_other.disjoint()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericRequiresIntegersView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericRequiresIntegersView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericRequiresIntegersView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "zero_through_nine") {
+        if (!zero_through_nine().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "ten_through_twenty") {
+        if (!ten_through_twenty().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "disjoint") {
+        if (!disjoint().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "alias_of_zero_through_nine") {
+        if (!alias_of_zero_through_nine().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "zero_through_nine_plus_five") {
+        if (!zero_through_nine_plus_five().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_zero_through_nine().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          zero_through_nine().IsAggregate() || zero_through_nine().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("zero_through_nine: ");
+        zero_through_nine().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !zero_through_nine().IsAggregate() && !zero_through_nine().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# zero_through_nine: UNREADABLE\n");
+      }
+    }
+
+    if (has_ten_through_twenty().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          ten_through_twenty().IsAggregate() || ten_through_twenty().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("ten_through_twenty: ");
+        ten_through_twenty().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !ten_through_twenty().IsAggregate() && !ten_through_twenty().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# ten_through_twenty: UNREADABLE\n");
+      }
+    }
+
+    if (has_disjoint().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          disjoint().IsAggregate() || disjoint().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("disjoint: ");
+        disjoint().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !disjoint().IsAggregate() && !disjoint().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# disjoint: UNREADABLE\n");
+      }
+    }
+
+    if (has_ztn_plus_ttt().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          ztn_plus_ttt().IsAggregate() || ztn_plus_ttt().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# ztn_plus_ttt: ");
+        ztn_plus_ttt().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# ztn_plus_ttt: UNREADABLE\n");
+      }
+    }
+
+    if (has_alias_of_zero_through_nine().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          alias_of_zero_through_nine().IsAggregate() || alias_of_zero_through_nine().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("alias_of_zero_through_nine: ");
+        alias_of_zero_through_nine().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !alias_of_zero_through_nine().IsAggregate() && !alias_of_zero_through_nine().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# alias_of_zero_through_nine: UNREADABLE\n");
+      }
+    }
+
+    if (has_zero_through_nine_plus_five().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          zero_through_nine_plus_five().IsAggregate() || zero_through_nine_plus_five().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("zero_through_nine_plus_five: ");
+        zero_through_nine_plus_five().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !zero_through_nine_plus_five().IsAggregate() && !zero_through_nine_plus_five().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# zero_through_nine_plus_five: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, RequiresIntegers::EmbossReservedValidatorForZeroThroughNine>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ zero_through_nine() const;
+  ::emboss::support::Maybe<bool> has_zero_through_nine() const;
+
+ public:
+  typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, RequiresIntegers::EmbossReservedValidatorForTenThroughTwenty>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ ten_through_twenty() const;
+  ::emboss::support::Maybe<bool> has_ten_through_twenty() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, RequiresIntegers::EmbossReservedValidatorForDisjoint>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ disjoint() const;
+  ::emboss::support::Maybe<bool> has_disjoint() const;
+
+ public:
+  class EmbossReservedVirtualZtnPlusTttView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedVirtualZtnPlusTttView(
+        const GenericRequiresIntegersView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualZtnPlusTttView() = delete;
+    EmbossReservedVirtualZtnPlusTttView(const EmbossReservedVirtualZtnPlusTttView &) = default;
+    EmbossReservedVirtualZtnPlusTttView(EmbossReservedVirtualZtnPlusTttView &&) = default;
+    EmbossReservedVirtualZtnPlusTttView &operator=(const EmbossReservedVirtualZtnPlusTttView &) =
+        default;
+    EmbossReservedVirtualZtnPlusTttView &operator=(EmbossReservedVirtualZtnPlusTttView &&) =
+        default;
+    ~EmbossReservedVirtualZtnPlusTttView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_ztn_plus_ttt().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.zero_through_nine();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = view_.ten_through_twenty();
+      const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_4);
+
+      return emboss_reserved_local_subexpr_5;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)), ::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value)), ::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(19LL)))).ValueOr(false);
+    }
+
+    const GenericRequiresIntegersView view_;
+  };
+  EmbossReservedVirtualZtnPlusTttView ztn_plus_ttt() const;
+  ::emboss::support::Maybe<bool> has_ztn_plus_ttt() const;
+
+ public:
+  class EmbossReservedVirtualAliasOfZeroThroughNineView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedVirtualAliasOfZeroThroughNineView(
+        const GenericRequiresIntegersView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualAliasOfZeroThroughNineView() = delete;
+    EmbossReservedVirtualAliasOfZeroThroughNineView(const EmbossReservedVirtualAliasOfZeroThroughNineView &) = default;
+    EmbossReservedVirtualAliasOfZeroThroughNineView(EmbossReservedVirtualAliasOfZeroThroughNineView &&) = default;
+    EmbossReservedVirtualAliasOfZeroThroughNineView &operator=(const EmbossReservedVirtualAliasOfZeroThroughNineView &) =
+        default;
+    EmbossReservedVirtualAliasOfZeroThroughNineView &operator=(EmbossReservedVirtualAliasOfZeroThroughNineView &&) =
+        default;
+    ~EmbossReservedVirtualAliasOfZeroThroughNineView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_alias_of_zero_through_nine().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+    bool TryToWrite(::std::int32_t emboss_reserved_local_value) {
+      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value);
+      if (!CouldWriteValue(emboss_reserved_local_value)) return false;
+      return view_.zero_through_nine().TryToWrite(
+          emboss_reserved_local_maybe_new_value.ValueOrDefault());
+    }
+    void Write(::std::int32_t emboss_reserved_local_value) {
+      const bool result = TryToWrite(emboss_reserved_local_value);
+      (void)result;
+      EMBOSS_CHECK(result);
+    }
+    void UncheckedWrite(::std::int32_t emboss_reserved_local_value) {
+      view_.zero_through_nine().UncheckedWrite((::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value)).ValueOrDefault());
+    }
+    bool CouldWriteValue(::std::int32_t emboss_reserved_local_value) {
+      if (!ValueIsOk(emboss_reserved_local_value)) return false;
+      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value);
+      if (!emboss_reserved_local_maybe_new_value.Known()) return false;
+      return view_.zero_through_nine().CouldWriteValue(
+          emboss_reserved_local_maybe_new_value.ValueOrDefault());
+    }
+    template <class Stream>
+    bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) {
+      return ::emboss::support::ReadIntegerFromTextStream(
+          this, emboss_reserved_local_stream);
+    }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.zero_through_nine();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+
+      return emboss_reserved_local_subexpr_2;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value)), ::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(7LL)))).ValueOr(false);
+    }
+
+    const GenericRequiresIntegersView view_;
+  };
+  EmbossReservedVirtualAliasOfZeroThroughNineView alias_of_zero_through_nine() const;
+  ::emboss::support::Maybe<bool> has_alias_of_zero_through_nine() const;
+
+ public:
+  class EmbossReservedVirtualZeroThroughNinePlusFiveView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedVirtualZeroThroughNinePlusFiveView(
+        const GenericRequiresIntegersView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualZeroThroughNinePlusFiveView() = delete;
+    EmbossReservedVirtualZeroThroughNinePlusFiveView(const EmbossReservedVirtualZeroThroughNinePlusFiveView &) = default;
+    EmbossReservedVirtualZeroThroughNinePlusFiveView(EmbossReservedVirtualZeroThroughNinePlusFiveView &&) = default;
+    EmbossReservedVirtualZeroThroughNinePlusFiveView &operator=(const EmbossReservedVirtualZeroThroughNinePlusFiveView &) =
+        default;
+    EmbossReservedVirtualZeroThroughNinePlusFiveView &operator=(EmbossReservedVirtualZeroThroughNinePlusFiveView &&) =
+        default;
+    ~EmbossReservedVirtualZeroThroughNinePlusFiveView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_zero_through_nine_plus_five().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+    bool TryToWrite(::std::int32_t emboss_reserved_local_value) {
+      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
+      if (!CouldWriteValue(emboss_reserved_local_value)) return false;
+      return view_.zero_through_nine().TryToWrite(
+          emboss_reserved_local_maybe_new_value.ValueOrDefault());
+    }
+    void Write(::std::int32_t emboss_reserved_local_value) {
+      const bool result = TryToWrite(emboss_reserved_local_value);
+      (void)result;
+      EMBOSS_CHECK(result);
+    }
+    void UncheckedWrite(::std::int32_t emboss_reserved_local_value) {
+      view_.zero_through_nine().UncheckedWrite((::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)))).ValueOrDefault());
+    }
+    bool CouldWriteValue(::std::int32_t emboss_reserved_local_value) {
+      if (!ValueIsOk(emboss_reserved_local_value)) return false;
+      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
+      if (!emboss_reserved_local_maybe_new_value.Known()) return false;
+      return view_.zero_through_nine().CouldWriteValue(
+          emboss_reserved_local_maybe_new_value.ValueOrDefault());
+    }
+    template <class Stream>
+    bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) {
+      return ::emboss::support::ReadIntegerFromTextStream(
+          this, emboss_reserved_local_stream);
+    }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.zero_through_nine();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)));
+
+      return emboss_reserved_local_subexpr_3;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)), ::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value)), ::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)))).ValueOr(false);
+    }
+
+    const GenericRequiresIntegersView view_;
+  };
+  EmbossReservedVirtualZeroThroughNinePlusFiveView zero_through_nine_plus_five() const;
+  ::emboss::support::Maybe<bool> has_zero_through_nine_plus_five() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericRequiresIntegersView;
+};
+using RequiresIntegersView =
+    GenericRequiresIntegersView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using RequiresIntegersWriter =
+    GenericRequiresIntegersView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericRequiresIntegersView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericRequiresIntegersView<
+    GenericRequiresIntegersView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericRequiresIntegersView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeRequiresIntegersView( T &&emboss_reserved_local_arg) {
+  return GenericRequiresIntegersView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericRequiresIntegersView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeRequiresIntegersView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericRequiresIntegersView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericRequiresIntegersView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedRequiresIntegersView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericRequiresIntegersView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+
+
+
+
+namespace RequiresBools {
+
+
+namespace EmbossReservedAnonymousField2 {
+struct EmbossReservedValidatorForMustBeTrue {
+  template <typename ValueType>
+  static constexpr bool ValueIsOk(ValueType emboss_reserved_local_value) {
+    return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+           (::emboss::support::Maybe</**/bool>(emboss_reserved_local_value)).ValueOrDefault();
+  }
+};
+
+
+}  // namespace EmbossReservedAnonymousField2
+
+
+
+namespace EmbossReservedAnonymousField2 {
+struct EmbossReservedValidatorForMustBeFalse {
+  template <typename ValueType>
+  static constexpr bool ValueIsOk(ValueType emboss_reserved_local_value) {
+    return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+           (::emboss::support::Equal</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(emboss_reserved_local_value), ::emboss::support::Maybe</**/bool>(false))).ValueOrDefault();
+  }
+};
+
+
+}  // namespace EmbossReservedAnonymousField2
+
+
+
+
+
+namespace EmbossReservedAnonymousField2 {
+
+}  // namespace EmbossReservedAnonymousField2
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField2View;
+
+template <class Storage>
+class GenericEmbossReservedAnonymousField2View final {
+ public:
+  GenericEmbossReservedAnonymousField2View() : backing_() {}
+  explicit GenericEmbossReservedAnonymousField2View(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEmbossReservedAnonymousField2View(
+      const GenericEmbossReservedAnonymousField2View<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericEmbossReservedAnonymousField2View<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericEmbossReservedAnonymousField2View(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericEmbossReservedAnonymousField2View(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEmbossReservedAnonymousField2View<Storage> &operator=(
+      const GenericEmbossReservedAnonymousField2View<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_a().Known()) return false;
+    if (has_a().ValueOrDefault() && !a().Ok()) return false;
+
+
+    if (!has_b().Known()) return false;
+    if (has_b().ValueOrDefault() && !b().Ok()) return false;
+
+
+    if (!has_must_be_true().Known()) return false;
+    if (has_must_be_true().ValueOrDefault() && !must_be_true().Ok()) return false;
+
+
+    if (!has_must_be_false().Known()) return false;
+    if (has_must_be_false().ValueOrDefault() && !must_be_false().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBits().Known()) return false;
+    if (has_IntrinsicSizeInBits().ValueOrDefault() && !IntrinsicSizeInBits().Ok()) return false;
+
+
+    if (!has_MaxSizeInBits().Known()) return false;
+    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok()) return false;
+
+
+    if (!has_MinSizeInBits().Known()) return false;
+    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBits().Ok() &&
+           backing_.SizeInBits() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBits().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBits() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBits().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBits().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericEmbossReservedAnonymousField2View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_a().Known()) return false;
+    if (!emboss_reserved_local_other.has_a().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        !has_a().ValueOrDefault())
+      return false;
+    if (has_a().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        has_a().ValueOrDefault() &&
+        !a().Equals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (!has_b().Known()) return false;
+    if (!emboss_reserved_local_other.has_b().Known()) return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        !has_b().ValueOrDefault())
+      return false;
+    if (has_b().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_b().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        has_b().ValueOrDefault() &&
+        !b().Equals(emboss_reserved_local_other.b()))
+      return false;
+
+
+
+    if (!has_must_be_true().Known()) return false;
+    if (!emboss_reserved_local_other.has_must_be_true().Known()) return false;
+
+    if (emboss_reserved_local_other.has_must_be_true().ValueOrDefault() &&
+        !has_must_be_true().ValueOrDefault())
+      return false;
+    if (has_must_be_true().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_must_be_true().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_must_be_true().ValueOrDefault() &&
+        has_must_be_true().ValueOrDefault() &&
+        !must_be_true().Equals(emboss_reserved_local_other.must_be_true()))
+      return false;
+
+
+
+    if (!has_must_be_false().Known()) return false;
+    if (!emboss_reserved_local_other.has_must_be_false().Known()) return false;
+
+    if (emboss_reserved_local_other.has_must_be_false().ValueOrDefault() &&
+        !has_must_be_false().ValueOrDefault())
+      return false;
+    if (has_must_be_false().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_must_be_false().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_must_be_false().ValueOrDefault() &&
+        has_must_be_false().ValueOrDefault() &&
+        !must_be_false().Equals(emboss_reserved_local_other.must_be_false()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericEmbossReservedAnonymousField2View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        !has_a().ValueOr(false))
+      return false;
+    if (has_a().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        has_a().ValueOr(false) &&
+        !a().UncheckedEquals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        !has_b().ValueOr(false))
+      return false;
+    if (has_b().ValueOr(false) &&
+        !emboss_reserved_local_other.has_b().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        has_b().ValueOr(false) &&
+        !b().UncheckedEquals(emboss_reserved_local_other.b()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_must_be_true().ValueOr(false) &&
+        !has_must_be_true().ValueOr(false))
+      return false;
+    if (has_must_be_true().ValueOr(false) &&
+        !emboss_reserved_local_other.has_must_be_true().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_must_be_true().ValueOr(false) &&
+        has_must_be_true().ValueOr(false) &&
+        !must_be_true().UncheckedEquals(emboss_reserved_local_other.must_be_true()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_must_be_false().ValueOr(false) &&
+        !has_must_be_false().ValueOr(false))
+      return false;
+    if (has_must_be_false().ValueOr(false) &&
+        !emboss_reserved_local_other.has_must_be_false().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_must_be_false().ValueOr(false) &&
+        has_must_be_false().ValueOr(false) &&
+        !must_be_false().UncheckedEquals(emboss_reserved_local_other.must_be_false()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericEmbossReservedAnonymousField2View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericEmbossReservedAnonymousField2View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericEmbossReservedAnonymousField2View<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "a") {
+        if (!a().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "b") {
+        if (!b().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "must_be_true") {
+        if (!must_be_true().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "must_be_false") {
+        if (!must_be_false().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_a().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a().IsAggregate() || a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a: ");
+        a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a().IsAggregate() && !a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a: UNREADABLE\n");
+      }
+    }
+
+    if (has_b().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b().IsAggregate() || b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("b: ");
+        b().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !b().IsAggregate() && !b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b: UNREADABLE\n");
+      }
+    }
+
+    if (has_must_be_true().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          must_be_true().IsAggregate() || must_be_true().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("must_be_true: ");
+        must_be_true().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !must_be_true().IsAggregate() && !must_be_true().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# must_be_true: UNREADABLE\n");
+      }
+    }
+
+    if (has_must_be_false().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          must_be_false().IsAggregate() || must_be_false().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("must_be_false: ");
+        must_be_false().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !must_be_false().IsAggregate() && !must_be_false().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# must_be_false: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ a() const;
+  ::emboss::support::Maybe<bool> has_a() const;
+
+ public:
+  typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 1>>
+
+ b() const;
+  ::emboss::support::Maybe<bool> has_b() const;
+
+ public:
+  typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, EmbossReservedAnonymousField2::EmbossReservedValidatorForMustBeTrue>,
+    typename Storage::template OffsetStorageType</**/0, 2>>
+
+ must_be_true() const;
+  ::emboss::support::Maybe<bool> has_must_be_true() const;
+
+ public:
+  typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, EmbossReservedAnonymousField2::EmbossReservedValidatorForMustBeFalse>,
+    typename Storage::template OffsetStorageType</**/0, 3>>
+
+ must_be_false() const;
+  ::emboss::support::Maybe<bool> has_must_be_false() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView IntrinsicSizeInBits() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBitsView() {}
+    EmbossReservedDollarVirtualMaxSizeInBitsView(const EmbossReservedDollarVirtualMaxSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView(EmbossReservedDollarVirtualMaxSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(const EmbossReservedDollarVirtualMaxSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(EmbossReservedDollarVirtualMaxSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBitsView MaxSizeInBits() {
+    return EmbossReservedDollarVirtualMaxSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBitsView() {}
+    EmbossReservedDollarVirtualMinSizeInBitsView(const EmbossReservedDollarVirtualMinSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView(EmbossReservedDollarVirtualMinSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(const EmbossReservedDollarVirtualMinSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(EmbossReservedDollarVirtualMinSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBitsView MinSizeInBits() {
+    return EmbossReservedDollarVirtualMinSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericEmbossReservedAnonymousField2View;
+};
+using EmbossReservedAnonymousField2View =
+    GenericEmbossReservedAnonymousField2View</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using EmbossReservedAnonymousField2Writer =
+    GenericEmbossReservedAnonymousField2View</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField2View {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField2View<
+    GenericEmbossReservedAnonymousField2View<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericEmbossReservedAnonymousField2View<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeEmbossReservedAnonymousField2View( T &&emboss_reserved_local_arg) {
+  return GenericEmbossReservedAnonymousField2View<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericEmbossReservedAnonymousField2View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeEmbossReservedAnonymousField2View( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericEmbossReservedAnonymousField2View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericEmbossReservedAnonymousField2View<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedEmbossReservedAnonymousField2View(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericEmbossReservedAnonymousField2View<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+}  // namespace RequiresBools
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericRequiresBoolsView;
+
+template <class Storage>
+class GenericRequiresBoolsView final {
+ public:
+  GenericRequiresBoolsView() : backing_() {}
+  explicit GenericRequiresBoolsView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericRequiresBoolsView(
+      const GenericRequiresBoolsView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericRequiresBoolsView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericRequiresBoolsView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericRequiresBoolsView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericRequiresBoolsView<Storage> &operator=(
+      const GenericRequiresBoolsView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_emboss_reserved_anonymous_field_2().Known()) return false;
+    if (has_emboss_reserved_anonymous_field_2().ValueOrDefault() && !emboss_reserved_anonymous_field_2().Ok()) return false;
+
+
+    if (!has_a().Known()) return false;
+    if (has_a().ValueOrDefault() && !a().Ok()) return false;
+
+
+    if (!has_b().Known()) return false;
+    if (has_b().ValueOrDefault() && !b().Ok()) return false;
+
+
+    if (!has_must_be_true().Known()) return false;
+    if (has_must_be_true().ValueOrDefault() && !must_be_true().Ok()) return false;
+
+
+    if (!has_must_be_false().Known()) return false;
+    if (has_must_be_false().ValueOrDefault() && !must_be_false().Ok()) return false;
+
+
+    if (!has_b_must_be_false().Known()) return false;
+    if (has_b_must_be_false().ValueOrDefault() && !b_must_be_false().Ok()) return false;
+
+
+    if (!has_alias_of_a_must_be_true().Known()) return false;
+    if (has_alias_of_a_must_be_true().ValueOrDefault() && !alias_of_a_must_be_true().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+    if (!(::emboss::support::Or</**/bool, bool, bool, bool>((a().Ok()    ? ::emboss::support::Maybe</**/bool>(static_cast</**/bool>(a().UncheckedRead()))    : ::emboss::support::Maybe</**/bool>()), (b().Ok()    ? ::emboss::support::Maybe</**/bool>(static_cast</**/bool>(b().UncheckedRead()))    : ::emboss::support::Maybe</**/bool>()))).ValueOr(false))
+      return false;
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericRequiresBoolsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_emboss_reserved_anonymous_field_2().Known()) return false;
+    if (!emboss_reserved_local_other.has_emboss_reserved_anonymous_field_2().Known()) return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_2().ValueOrDefault() &&
+        !has_emboss_reserved_anonymous_field_2().ValueOrDefault())
+      return false;
+    if (has_emboss_reserved_anonymous_field_2().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_emboss_reserved_anonymous_field_2().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_2().ValueOrDefault() &&
+        has_emboss_reserved_anonymous_field_2().ValueOrDefault() &&
+        !emboss_reserved_anonymous_field_2().Equals(emboss_reserved_local_other.emboss_reserved_anonymous_field_2()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericRequiresBoolsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_2().ValueOr(false) &&
+        !has_emboss_reserved_anonymous_field_2().ValueOr(false))
+      return false;
+    if (has_emboss_reserved_anonymous_field_2().ValueOr(false) &&
+        !emboss_reserved_local_other.has_emboss_reserved_anonymous_field_2().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_2().ValueOr(false) &&
+        has_emboss_reserved_anonymous_field_2().ValueOr(false) &&
+        !emboss_reserved_anonymous_field_2().UncheckedEquals(emboss_reserved_local_other.emboss_reserved_anonymous_field_2()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericRequiresBoolsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericRequiresBoolsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericRequiresBoolsView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "a") {
+        if (!a().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "b") {
+        if (!b().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "must_be_true") {
+        if (!must_be_true().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "must_be_false") {
+        if (!must_be_false().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "alias_of_a_must_be_true") {
+        if (!alias_of_a_must_be_true().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_a().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a().IsAggregate() || a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a: ");
+        a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a().IsAggregate() && !a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a: UNREADABLE\n");
+      }
+    }
+
+    if (has_b().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b().IsAggregate() || b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("b: ");
+        b().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !b().IsAggregate() && !b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b: UNREADABLE\n");
+      }
+    }
+
+    if (has_must_be_true().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          must_be_true().IsAggregate() || must_be_true().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("must_be_true: ");
+        must_be_true().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !must_be_true().IsAggregate() && !must_be_true().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# must_be_true: UNREADABLE\n");
+      }
+    }
+
+    if (has_must_be_false().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          must_be_false().IsAggregate() || must_be_false().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("must_be_false: ");
+        must_be_false().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !must_be_false().IsAggregate() && !must_be_false().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# must_be_false: UNREADABLE\n");
+      }
+    }
+
+    if (has_b_must_be_false().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b_must_be_false().IsAggregate() || b_must_be_false().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# b_must_be_false: ");
+        b_must_be_false().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b_must_be_false: UNREADABLE\n");
+      }
+    }
+
+    if (has_alias_of_a_must_be_true().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          alias_of_a_must_be_true().IsAggregate() || alias_of_a_must_be_true().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("alias_of_a_must_be_true: ");
+        alias_of_a_must_be_true().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !alias_of_a_must_be_true().IsAggregate() && !alias_of_a_must_be_true().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# alias_of_a_must_be_true: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ private:
+  typename ::emboss::test::RequiresBools::GenericEmbossReservedAnonymousField2View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ emboss_reserved_anonymous_field_2() const;
+  ::emboss::support::Maybe<bool> has_emboss_reserved_anonymous_field_2() const;
+
+ public:
+  auto a() const -> decltype(this->emboss_reserved_anonymous_field_2().a()) {
+   return has_a().ValueOrDefault() ? emboss_reserved_anonymous_field_2().a()
+                                          : decltype(this->emboss_reserved_anonymous_field_2().a())();
+  }
+  ::emboss::support::Maybe<bool> has_a() const;
+
+ public:
+  auto b() const -> decltype(this->emboss_reserved_anonymous_field_2().b()) {
+   return has_b().ValueOrDefault() ? emboss_reserved_anonymous_field_2().b()
+                                          : decltype(this->emboss_reserved_anonymous_field_2().b())();
+  }
+  ::emboss::support::Maybe<bool> has_b() const;
+
+ public:
+  auto must_be_true() const -> decltype(this->emboss_reserved_anonymous_field_2().must_be_true()) {
+   return has_must_be_true().ValueOrDefault() ? emboss_reserved_anonymous_field_2().must_be_true()
+                                          : decltype(this->emboss_reserved_anonymous_field_2().must_be_true())();
+  }
+  ::emboss::support::Maybe<bool> has_must_be_true() const;
+
+ public:
+  auto must_be_false() const -> decltype(this->emboss_reserved_anonymous_field_2().must_be_false()) {
+   return has_must_be_false().ValueOrDefault() ? emboss_reserved_anonymous_field_2().must_be_false()
+                                          : decltype(this->emboss_reserved_anonymous_field_2().must_be_false())();
+  }
+  ::emboss::support::Maybe<bool> has_must_be_false() const;
+
+ public:
+  class EmbossReservedVirtualBMustBeFalseView final {
+   public:
+    using ValueType = bool;
+
+    explicit EmbossReservedVirtualBMustBeFalseView(
+        const GenericRequiresBoolsView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualBMustBeFalseView() = delete;
+    EmbossReservedVirtualBMustBeFalseView(const EmbossReservedVirtualBMustBeFalseView &) = default;
+    EmbossReservedVirtualBMustBeFalseView(EmbossReservedVirtualBMustBeFalseView &&) = default;
+    EmbossReservedVirtualBMustBeFalseView &operator=(const EmbossReservedVirtualBMustBeFalseView &) =
+        default;
+    EmbossReservedVirtualBMustBeFalseView &operator=(EmbossReservedVirtualBMustBeFalseView &&) =
+        default;
+    ~EmbossReservedVirtualBMustBeFalseView() = default;
+
+    bool Read() const {
+      EMBOSS_CHECK(view_.has_b_must_be_false().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    bool UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteBooleanViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ bool> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.b();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/bool>(static_cast</**/bool>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/bool>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Equal</**/bool, bool, bool, bool>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/bool>(false));
+
+      return emboss_reserved_local_subexpr_3;
+    }
+
+    static constexpr bool ValueIsOk(
+        bool emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe</**/bool>(emboss_reserved_local_value).ValueOr(false);
+    }
+
+    const GenericRequiresBoolsView view_;
+  };
+  EmbossReservedVirtualBMustBeFalseView b_must_be_false() const;
+  ::emboss::support::Maybe<bool> has_b_must_be_false() const;
+
+ public:
+  class EmbossReservedVirtualAliasOfAMustBeTrueView final {
+   public:
+    using ValueType = bool;
+
+    explicit EmbossReservedVirtualAliasOfAMustBeTrueView(
+        const GenericRequiresBoolsView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualAliasOfAMustBeTrueView() = delete;
+    EmbossReservedVirtualAliasOfAMustBeTrueView(const EmbossReservedVirtualAliasOfAMustBeTrueView &) = default;
+    EmbossReservedVirtualAliasOfAMustBeTrueView(EmbossReservedVirtualAliasOfAMustBeTrueView &&) = default;
+    EmbossReservedVirtualAliasOfAMustBeTrueView &operator=(const EmbossReservedVirtualAliasOfAMustBeTrueView &) =
+        default;
+    EmbossReservedVirtualAliasOfAMustBeTrueView &operator=(EmbossReservedVirtualAliasOfAMustBeTrueView &&) =
+        default;
+    ~EmbossReservedVirtualAliasOfAMustBeTrueView() = default;
+
+    bool Read() const {
+      EMBOSS_CHECK(view_.has_alias_of_a_must_be_true().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    bool UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteBooleanViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+    bool TryToWrite(bool emboss_reserved_local_value) {
+      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value);
+      if (!CouldWriteValue(emboss_reserved_local_value)) return false;
+      return view_.a().TryToWrite(
+          emboss_reserved_local_maybe_new_value.ValueOrDefault());
+    }
+    void Write(bool emboss_reserved_local_value) {
+      const bool result = TryToWrite(emboss_reserved_local_value);
+      (void)result;
+      EMBOSS_CHECK(result);
+    }
+    void UncheckedWrite(bool emboss_reserved_local_value) {
+      view_.a().UncheckedWrite((::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value)).ValueOrDefault());
+    }
+    bool CouldWriteValue(bool emboss_reserved_local_value) {
+      if (!ValueIsOk(emboss_reserved_local_value)) return false;
+      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value);
+      if (!emboss_reserved_local_maybe_new_value.Known()) return false;
+      return view_.a().CouldWriteValue(
+          emboss_reserved_local_maybe_new_value.ValueOrDefault());
+    }
+    template <class Stream>
+    bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) {
+      return ::emboss::support::ReadIntegerFromTextStream(
+          this, emboss_reserved_local_stream);
+    }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ bool> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.a();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/bool>(static_cast</**/bool>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/bool>());
+
+      return emboss_reserved_local_subexpr_2;
+    }
+
+    static constexpr bool ValueIsOk(
+        bool emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe</**/bool>(emboss_reserved_local_value).ValueOr(false);
+    }
+
+    const GenericRequiresBoolsView view_;
+  };
+  EmbossReservedVirtualAliasOfAMustBeTrueView alias_of_a_must_be_true() const;
+  ::emboss::support::Maybe<bool> has_alias_of_a_must_be_true() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericRequiresBoolsView;
+};
+using RequiresBoolsView =
+    GenericRequiresBoolsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using RequiresBoolsWriter =
+    GenericRequiresBoolsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericRequiresBoolsView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericRequiresBoolsView<
+    GenericRequiresBoolsView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericRequiresBoolsView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeRequiresBoolsView( T &&emboss_reserved_local_arg) {
+  return GenericRequiresBoolsView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericRequiresBoolsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeRequiresBoolsView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericRequiresBoolsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericRequiresBoolsView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedRequiresBoolsView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericRequiresBoolsView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+namespace RequiresEnums {
+struct EmbossReservedValidatorForC {
+  template <typename ValueType>
+  static constexpr bool ValueIsOk(ValueType emboss_reserved_local_value) {
+    return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+           (::emboss::support::Or</**/bool, bool, bool, bool>(::emboss::support::Equal</**/::emboss::test::RequiresEnums::Enum, bool, ::emboss::test::RequiresEnums::Enum, ::emboss::test::RequiresEnums::Enum>(::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(static_cast</**/::emboss::test::RequiresEnums::Enum>(0))), ::emboss::support::Equal</**/::emboss::test::RequiresEnums::Enum, bool, ::emboss::test::RequiresEnums::Enum, ::emboss::test::RequiresEnums::Enum>(::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(static_cast</**/::emboss::test::RequiresEnums::Enum>(1))))).ValueOrDefault();
+  }
+};
+
+
+}  // namespace RequiresEnums
+
+
+
+
+
+
+
+namespace RequiresEnums {
+enum class Enum : ::std::uint64_t {
+  EN0 = static_cast</**/::std::int32_t>(0LL),
+  EN1 = static_cast</**/::std::int32_t>(1LL),
+  EN2 = static_cast</**/::std::int32_t>(2LL),
+  EN3 = static_cast</**/::std::int32_t>(3LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<Enum> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   Enum *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("EN0", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Enum::EN0;
+      return true;
+    }
+
+    if (!strcmp("EN1", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Enum::EN1;
+      return true;
+    }
+
+    if (!strcmp("EN2", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Enum::EN2;
+      return true;
+    }
+
+    if (!strcmp("EN3", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Enum::EN3;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      Enum emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Enum::EN0: return "EN0";
+
+      case Enum::EN1: return "EN1";
+
+      case Enum::EN2: return "EN2";
+
+      case Enum::EN3: return "EN3";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(Enum emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Enum::EN0: return true;
+
+      case Enum::EN1: return true;
+
+      case Enum::EN2: return true;
+
+      case Enum::EN3: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       Enum emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<Enum>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    Enum *emboss_reserved_local_result) {
+  return EnumTraits<Enum>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    Enum emboss_reserved_local_value) {
+  return EnumTraits<Enum>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(Enum emboss_reserved_local_value) {
+  return EnumTraits<Enum>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    Enum emboss_reserved_local_value) {
+  return EnumTraits<Enum>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+
+}  // namespace RequiresEnums
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericRequiresEnumsView;
+
+template <class Storage>
+class GenericRequiresEnumsView final {
+ public:
+  GenericRequiresEnumsView() : backing_() {}
+  explicit GenericRequiresEnumsView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericRequiresEnumsView(
+      const GenericRequiresEnumsView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericRequiresEnumsView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericRequiresEnumsView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericRequiresEnumsView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericRequiresEnumsView<Storage> &operator=(
+      const GenericRequiresEnumsView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+    using Enum = ::emboss::test::RequiresEnums::Enum;
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_a().Known()) return false;
+    if (has_a().ValueOrDefault() && !a().Ok()) return false;
+
+
+    if (!has_b().Known()) return false;
+    if (has_b().ValueOrDefault() && !b().Ok()) return false;
+
+
+    if (!has_c().Known()) return false;
+    if (has_c().ValueOrDefault() && !c().Ok()) return false;
+
+
+    if (!has_filtered_a().Known()) return false;
+    if (has_filtered_a().ValueOrDefault() && !filtered_a().Ok()) return false;
+
+
+    if (!has_alias_of_a().Known()) return false;
+    if (has_alias_of_a().ValueOrDefault() && !alias_of_a().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+    if (!(::emboss::support::Or</**/bool, bool, bool, bool>(::emboss::support::Equal</**/::emboss::test::RequiresEnums::Enum, bool, ::emboss::test::RequiresEnums::Enum, ::emboss::test::RequiresEnums::Enum>((a().Ok()    ? ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(static_cast</**/::emboss::test::RequiresEnums::Enum>(a().UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>()), ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(static_cast</**/::emboss::test::RequiresEnums::Enum>(0))), ::emboss::support::Equal</**/::emboss::test::RequiresEnums::Enum, bool, ::emboss::test::RequiresEnums::Enum, ::emboss::test::RequiresEnums::Enum>((b().Ok()    ? ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(static_cast</**/::emboss::test::RequiresEnums::Enum>(b().UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>()), ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(static_cast</**/::emboss::test::RequiresEnums::Enum>(0))))).ValueOr(false))
+      return false;
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericRequiresEnumsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_a().Known()) return false;
+    if (!emboss_reserved_local_other.has_a().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        !has_a().ValueOrDefault())
+      return false;
+    if (has_a().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        has_a().ValueOrDefault() &&
+        !a().Equals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (!has_b().Known()) return false;
+    if (!emboss_reserved_local_other.has_b().Known()) return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        !has_b().ValueOrDefault())
+      return false;
+    if (has_b().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_b().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        has_b().ValueOrDefault() &&
+        !b().Equals(emboss_reserved_local_other.b()))
+      return false;
+
+
+
+    if (!has_c().Known()) return false;
+    if (!emboss_reserved_local_other.has_c().Known()) return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOrDefault() &&
+        !has_c().ValueOrDefault())
+      return false;
+    if (has_c().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_c().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOrDefault() &&
+        has_c().ValueOrDefault() &&
+        !c().Equals(emboss_reserved_local_other.c()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericRequiresEnumsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        !has_a().ValueOr(false))
+      return false;
+    if (has_a().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        has_a().ValueOr(false) &&
+        !a().UncheckedEquals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        !has_b().ValueOr(false))
+      return false;
+    if (has_b().ValueOr(false) &&
+        !emboss_reserved_local_other.has_b().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        has_b().ValueOr(false) &&
+        !b().UncheckedEquals(emboss_reserved_local_other.b()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_c().ValueOr(false) &&
+        !has_c().ValueOr(false))
+      return false;
+    if (has_c().ValueOr(false) &&
+        !emboss_reserved_local_other.has_c().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOr(false) &&
+        has_c().ValueOr(false) &&
+        !c().UncheckedEquals(emboss_reserved_local_other.c()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericRequiresEnumsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericRequiresEnumsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericRequiresEnumsView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "a") {
+        if (!a().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "b") {
+        if (!b().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "c") {
+        if (!c().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "alias_of_a") {
+        if (!alias_of_a().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_a().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a().IsAggregate() || a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a: ");
+        a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a().IsAggregate() && !a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a: UNREADABLE\n");
+      }
+    }
+
+    if (has_b().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b().IsAggregate() || b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("b: ");
+        b().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !b().IsAggregate() && !b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b: UNREADABLE\n");
+      }
+    }
+
+    if (has_c().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          c().IsAggregate() || c().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("c: ");
+        c().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !c().IsAggregate() && !c().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# c: UNREADABLE\n");
+      }
+    }
+
+    if (has_filtered_a().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          filtered_a().IsAggregate() || filtered_a().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# filtered_a: ");
+        filtered_a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# filtered_a: UNREADABLE\n");
+      }
+    }
+
+    if (has_alias_of_a().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          alias_of_a().IsAggregate() || alias_of_a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("alias_of_a: ");
+        alias_of_a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !alias_of_a().IsAggregate() && !alias_of_a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# alias_of_a: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::RequiresEnums::Enum,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ a() const;
+  ::emboss::support::Maybe<bool> has_a() const;
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::RequiresEnums::Enum,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ b() const;
+  ::emboss::support::Maybe<bool> has_b() const;
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::RequiresEnums::Enum,
+    ::emboss::support::FixedSizeViewParameters<8, RequiresEnums::EmbossReservedValidatorForC>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ c() const;
+  ::emboss::support::Maybe<bool> has_c() const;
+
+ public:
+  class EmbossReservedVirtualFilteredAView final {
+   public:
+    using ValueType = ::emboss::test::RequiresEnums::Enum;
+
+    explicit EmbossReservedVirtualFilteredAView(
+        const GenericRequiresEnumsView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualFilteredAView() = delete;
+    EmbossReservedVirtualFilteredAView(const EmbossReservedVirtualFilteredAView &) = default;
+    EmbossReservedVirtualFilteredAView(EmbossReservedVirtualFilteredAView &&) = default;
+    EmbossReservedVirtualFilteredAView &operator=(const EmbossReservedVirtualFilteredAView &) =
+        default;
+    EmbossReservedVirtualFilteredAView &operator=(EmbossReservedVirtualFilteredAView &&) =
+        default;
+    ~EmbossReservedVirtualFilteredAView() = default;
+
+    ::emboss::test::RequiresEnums::Enum Read() const {
+      EMBOSS_CHECK(view_.has_filtered_a().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::emboss::test::RequiresEnums::Enum UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteEnumViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::emboss::test::RequiresEnums::Enum> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.a();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(static_cast</**/::emboss::test::RequiresEnums::Enum>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Equal</**/::emboss::test::RequiresEnums::Enum, bool, ::emboss::test::RequiresEnums::Enum, ::emboss::test::RequiresEnums::Enum>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(static_cast</**/::emboss::test::RequiresEnums::Enum>(0)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::emboss::test::RequiresEnums::Enum, ::emboss::test::RequiresEnums::Enum, bool, ::emboss::test::RequiresEnums::Enum, ::emboss::test::RequiresEnums::Enum>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(static_cast</**/::emboss::test::RequiresEnums::Enum>(1)), emboss_reserved_local_subexpr_2);
+
+      return emboss_reserved_local_subexpr_4;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::emboss::test::RequiresEnums::Enum emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Equal</**/::emboss::test::RequiresEnums::Enum, bool, ::emboss::test::RequiresEnums::Enum, ::emboss::test::RequiresEnums::Enum>(::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(static_cast</**/::emboss::test::RequiresEnums::Enum>(1))).ValueOr(false);
+    }
+
+    const GenericRequiresEnumsView view_;
+  };
+  EmbossReservedVirtualFilteredAView filtered_a() const;
+  ::emboss::support::Maybe<bool> has_filtered_a() const;
+
+ public:
+  class EmbossReservedVirtualAliasOfAView final {
+   public:
+    using ValueType = ::emboss::test::RequiresEnums::Enum;
+
+    explicit EmbossReservedVirtualAliasOfAView(
+        const GenericRequiresEnumsView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualAliasOfAView() = delete;
+    EmbossReservedVirtualAliasOfAView(const EmbossReservedVirtualAliasOfAView &) = default;
+    EmbossReservedVirtualAliasOfAView(EmbossReservedVirtualAliasOfAView &&) = default;
+    EmbossReservedVirtualAliasOfAView &operator=(const EmbossReservedVirtualAliasOfAView &) =
+        default;
+    EmbossReservedVirtualAliasOfAView &operator=(EmbossReservedVirtualAliasOfAView &&) =
+        default;
+    ~EmbossReservedVirtualAliasOfAView() = default;
+
+    ::emboss::test::RequiresEnums::Enum Read() const {
+      EMBOSS_CHECK(view_.has_alias_of_a().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::emboss::test::RequiresEnums::Enum UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteEnumViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+    bool TryToWrite(::emboss::test::RequiresEnums::Enum emboss_reserved_local_value) {
+      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value);
+      if (!CouldWriteValue(emboss_reserved_local_value)) return false;
+      return view_.a().TryToWrite(
+          emboss_reserved_local_maybe_new_value.ValueOrDefault());
+    }
+    void Write(::emboss::test::RequiresEnums::Enum emboss_reserved_local_value) {
+      const bool result = TryToWrite(emboss_reserved_local_value);
+      (void)result;
+      EMBOSS_CHECK(result);
+    }
+    void UncheckedWrite(::emboss::test::RequiresEnums::Enum emboss_reserved_local_value) {
+      view_.a().UncheckedWrite((::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value)).ValueOrDefault());
+    }
+    bool CouldWriteValue(::emboss::test::RequiresEnums::Enum emboss_reserved_local_value) {
+      if (!ValueIsOk(emboss_reserved_local_value)) return false;
+      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value);
+      if (!emboss_reserved_local_maybe_new_value.Known()) return false;
+      return view_.a().CouldWriteValue(
+          emboss_reserved_local_maybe_new_value.ValueOrDefault());
+    }
+    template <class Stream>
+    bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) {
+      return ::emboss::support::ReadIntegerFromTextStream(
+          this, emboss_reserved_local_stream);
+    }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::emboss::test::RequiresEnums::Enum> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.a();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(static_cast</**/::emboss::test::RequiresEnums::Enum>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>());
+
+      return emboss_reserved_local_subexpr_2;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::emboss::test::RequiresEnums::Enum emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Equal</**/::emboss::test::RequiresEnums::Enum, bool, ::emboss::test::RequiresEnums::Enum, ::emboss::test::RequiresEnums::Enum>(::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::emboss::test::RequiresEnums::Enum>(static_cast</**/::emboss::test::RequiresEnums::Enum>(1))).ValueOr(false);
+    }
+
+    const GenericRequiresEnumsView view_;
+  };
+  EmbossReservedVirtualAliasOfAView alias_of_a() const;
+  ::emboss::support::Maybe<bool> has_alias_of_a() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericRequiresEnumsView;
+};
+using RequiresEnumsView =
+    GenericRequiresEnumsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using RequiresEnumsWriter =
+    GenericRequiresEnumsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericRequiresEnumsView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericRequiresEnumsView<
+    GenericRequiresEnumsView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericRequiresEnumsView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeRequiresEnumsView( T &&emboss_reserved_local_arg) {
+  return GenericRequiresEnumsView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericRequiresEnumsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeRequiresEnumsView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericRequiresEnumsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericRequiresEnumsView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedRequiresEnumsView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericRequiresEnumsView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+
+
+namespace RequiresWithOptionalFields {
+
+
+
+namespace EmbossReservedAnonymousField1 {
+struct EmbossReservedValidatorForBTrue {
+  template <typename ValueType>
+  static constexpr bool ValueIsOk(ValueType emboss_reserved_local_value) {
+    return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+           (::emboss::support::Maybe</**/bool>(emboss_reserved_local_value)).ValueOrDefault();
+  }
+};
+
+
+}  // namespace EmbossReservedAnonymousField1
+
+
+
+
+
+namespace EmbossReservedAnonymousField1 {
+
+}  // namespace EmbossReservedAnonymousField1
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View;
+
+template <class Storage>
+class GenericEmbossReservedAnonymousField1View final {
+ public:
+  GenericEmbossReservedAnonymousField1View() : backing_() {}
+  explicit GenericEmbossReservedAnonymousField1View(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEmbossReservedAnonymousField1View(
+      const GenericEmbossReservedAnonymousField1View<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericEmbossReservedAnonymousField1View(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericEmbossReservedAnonymousField1View(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEmbossReservedAnonymousField1View<Storage> &operator=(
+      const GenericEmbossReservedAnonymousField1View<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_a().Known()) return false;
+    if (has_a().ValueOrDefault() && !a().Ok()) return false;
+
+
+    if (!has_b_exists().Known()) return false;
+    if (has_b_exists().ValueOrDefault() && !b_exists().Ok()) return false;
+
+
+    if (!has_b().Known()) return false;
+    if (has_b().ValueOrDefault() && !b().Ok()) return false;
+
+
+    if (!has_b_true().Known()) return false;
+    if (has_b_true().ValueOrDefault() && !b_true().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBits().Known()) return false;
+    if (has_IntrinsicSizeInBits().ValueOrDefault() && !IntrinsicSizeInBits().Ok()) return false;
+
+
+    if (!has_MaxSizeInBits().Known()) return false;
+    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok()) return false;
+
+
+    if (!has_MinSizeInBits().Known()) return false;
+    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBits().Ok() &&
+           backing_.SizeInBits() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBits().UncheckedRead());
+  }
+  ::std::size_t SizeInBits() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBits().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBits().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_a().Known()) return false;
+    if (!emboss_reserved_local_other.has_a().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        !has_a().ValueOrDefault())
+      return false;
+    if (has_a().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        has_a().ValueOrDefault() &&
+        !a().Equals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (!has_b_exists().Known()) return false;
+    if (!emboss_reserved_local_other.has_b_exists().Known()) return false;
+
+    if (emboss_reserved_local_other.has_b_exists().ValueOrDefault() &&
+        !has_b_exists().ValueOrDefault())
+      return false;
+    if (has_b_exists().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_b_exists().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_b_exists().ValueOrDefault() &&
+        has_b_exists().ValueOrDefault() &&
+        !b_exists().Equals(emboss_reserved_local_other.b_exists()))
+      return false;
+
+
+
+    if (!has_b().Known()) return false;
+    if (!emboss_reserved_local_other.has_b().Known()) return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        !has_b().ValueOrDefault())
+      return false;
+    if (has_b().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_b().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        has_b().ValueOrDefault() &&
+        !b().Equals(emboss_reserved_local_other.b()))
+      return false;
+
+
+
+    if (!has_b_true().Known()) return false;
+    if (!emboss_reserved_local_other.has_b_true().Known()) return false;
+
+    if (emboss_reserved_local_other.has_b_true().ValueOrDefault() &&
+        !has_b_true().ValueOrDefault())
+      return false;
+    if (has_b_true().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_b_true().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_b_true().ValueOrDefault() &&
+        has_b_true().ValueOrDefault() &&
+        !b_true().Equals(emboss_reserved_local_other.b_true()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        !has_a().ValueOr(false))
+      return false;
+    if (has_a().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        has_a().ValueOr(false) &&
+        !a().UncheckedEquals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_b_exists().ValueOr(false) &&
+        !has_b_exists().ValueOr(false))
+      return false;
+    if (has_b_exists().ValueOr(false) &&
+        !emboss_reserved_local_other.has_b_exists().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_b_exists().ValueOr(false) &&
+        has_b_exists().ValueOr(false) &&
+        !b_exists().UncheckedEquals(emboss_reserved_local_other.b_exists()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        !has_b().ValueOr(false))
+      return false;
+    if (has_b().ValueOr(false) &&
+        !emboss_reserved_local_other.has_b().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        has_b().ValueOr(false) &&
+        !b().UncheckedEquals(emboss_reserved_local_other.b()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_b_true().ValueOr(false) &&
+        !has_b_true().ValueOr(false))
+      return false;
+    if (has_b_true().ValueOr(false) &&
+        !emboss_reserved_local_other.has_b_true().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_b_true().ValueOr(false) &&
+        has_b_true().ValueOr(false) &&
+        !b_true().UncheckedEquals(emboss_reserved_local_other.b_true()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "a") {
+        if (!a().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "b_exists") {
+        if (!b_exists().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "b") {
+        if (!b().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "b_true") {
+        if (!b_true().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_a().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a().IsAggregate() || a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a: ");
+        a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a().IsAggregate() && !a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a: UNREADABLE\n");
+      }
+    }
+
+    if (has_b_exists().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b_exists().IsAggregate() || b_exists().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("b_exists: ");
+        b_exists().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !b_exists().IsAggregate() && !b_exists().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b_exists: UNREADABLE\n");
+      }
+    }
+
+    if (has_b().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b().IsAggregate() || b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("b: ");
+        b().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !b().IsAggregate() && !b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b: UNREADABLE\n");
+      }
+    }
+
+    if (has_b_true().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b_true().IsAggregate() || b_true().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("b_true: ");
+        b_true().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !b_true().IsAggregate() && !b_true().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b_true: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ a() const;
+  ::emboss::support::Maybe<bool> has_a() const;
+
+ public:
+  typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 1>>
+
+ b_exists() const;
+  ::emboss::support::Maybe<bool> has_b_exists() const;
+
+ public:
+  typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 2>>
+
+ b() const;
+  ::emboss::support::Maybe<bool> has_b() const;
+
+ public:
+  typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, EmbossReservedAnonymousField1::EmbossReservedValidatorForBTrue>,
+    typename Storage::template OffsetStorageType</**/0, 2>>
+
+ b_true() const;
+  ::emboss::support::Maybe<bool> has_b_true() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBitsView(
+        const GenericEmbossReservedAnonymousField1View &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBits().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.b_exists();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/bool>(static_cast</**/bool>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/bool>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), emboss_reserved_local_subexpr_3, emboss_reserved_local_subexpr_3);
+
+      return emboss_reserved_local_subexpr_4;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericEmbossReservedAnonymousField1View view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBitsView IntrinsicSizeInBits() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBitsView() {}
+    EmbossReservedDollarVirtualMaxSizeInBitsView(const EmbossReservedDollarVirtualMaxSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView(EmbossReservedDollarVirtualMaxSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(const EmbossReservedDollarVirtualMaxSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(EmbossReservedDollarVirtualMaxSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBitsView MaxSizeInBits() {
+    return EmbossReservedDollarVirtualMaxSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBitsView() {}
+    EmbossReservedDollarVirtualMinSizeInBitsView(const EmbossReservedDollarVirtualMinSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView(EmbossReservedDollarVirtualMinSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(const EmbossReservedDollarVirtualMinSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(EmbossReservedDollarVirtualMinSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBitsView MinSizeInBits() {
+    return EmbossReservedDollarVirtualMinSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericEmbossReservedAnonymousField1View;
+};
+using EmbossReservedAnonymousField1View =
+    GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using EmbossReservedAnonymousField1Writer =
+    GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View<
+    GenericEmbossReservedAnonymousField1View<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericEmbossReservedAnonymousField1View<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeEmbossReservedAnonymousField1View( T &&emboss_reserved_local_arg) {
+  return GenericEmbossReservedAnonymousField1View<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeEmbossReservedAnonymousField1View( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericEmbossReservedAnonymousField1View<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedEmbossReservedAnonymousField1View(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericEmbossReservedAnonymousField1View<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+}  // namespace RequiresWithOptionalFields
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericRequiresWithOptionalFieldsView;
+
+template <class Storage>
+class GenericRequiresWithOptionalFieldsView final {
+ public:
+  GenericRequiresWithOptionalFieldsView() : backing_() {}
+  explicit GenericRequiresWithOptionalFieldsView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericRequiresWithOptionalFieldsView(
+      const GenericRequiresWithOptionalFieldsView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericRequiresWithOptionalFieldsView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericRequiresWithOptionalFieldsView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericRequiresWithOptionalFieldsView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericRequiresWithOptionalFieldsView<Storage> &operator=(
+      const GenericRequiresWithOptionalFieldsView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_emboss_reserved_anonymous_field_1().Known()) return false;
+    if (has_emboss_reserved_anonymous_field_1().ValueOrDefault() && !emboss_reserved_anonymous_field_1().Ok()) return false;
+
+
+    if (!has_a().Known()) return false;
+    if (has_a().ValueOrDefault() && !a().Ok()) return false;
+
+
+    if (!has_b_exists().Known()) return false;
+    if (has_b_exists().ValueOrDefault() && !b_exists().Ok()) return false;
+
+
+    if (!has_b().Known()) return false;
+    if (has_b().ValueOrDefault() && !b().Ok()) return false;
+
+
+    if (!has_b_true().Known()) return false;
+    if (has_b_true().ValueOrDefault() && !b_true().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+    if (!(::emboss::support::Or</**/bool, bool, bool, bool>((a().Ok()    ? ::emboss::support::Maybe</**/bool>(static_cast</**/bool>(a().UncheckedRead()))    : ::emboss::support::Maybe</**/bool>()), (b().Ok()    ? ::emboss::support::Maybe</**/bool>(static_cast</**/bool>(b().UncheckedRead()))    : ::emboss::support::Maybe</**/bool>()))).ValueOr(false))
+      return false;
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericRequiresWithOptionalFieldsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_emboss_reserved_anonymous_field_1().Known()) return false;
+    if (!emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().Known()) return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        !has_emboss_reserved_anonymous_field_1().ValueOrDefault())
+      return false;
+    if (has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        !emboss_reserved_anonymous_field_1().Equals(emboss_reserved_local_other.emboss_reserved_anonymous_field_1()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericRequiresWithOptionalFieldsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        !has_emboss_reserved_anonymous_field_1().ValueOr(false))
+      return false;
+    if (has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        !emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        !emboss_reserved_anonymous_field_1().UncheckedEquals(emboss_reserved_local_other.emboss_reserved_anonymous_field_1()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericRequiresWithOptionalFieldsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericRequiresWithOptionalFieldsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericRequiresWithOptionalFieldsView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "a") {
+        if (!a().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "b_exists") {
+        if (!b_exists().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "b") {
+        if (!b().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "b_true") {
+        if (!b_true().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_a().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a().IsAggregate() || a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a: ");
+        a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a().IsAggregate() && !a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a: UNREADABLE\n");
+      }
+    }
+
+    if (has_b_exists().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b_exists().IsAggregate() || b_exists().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("b_exists: ");
+        b_exists().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !b_exists().IsAggregate() && !b_exists().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b_exists: UNREADABLE\n");
+      }
+    }
+
+    if (has_b().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b().IsAggregate() || b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("b: ");
+        b().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !b().IsAggregate() && !b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b: UNREADABLE\n");
+      }
+    }
+
+    if (has_b_true().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b_true().IsAggregate() || b_true().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("b_true: ");
+        b_true().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !b_true().IsAggregate() && !b_true().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b_true: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ private:
+  typename ::emboss::test::RequiresWithOptionalFields::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ emboss_reserved_anonymous_field_1() const;
+  ::emboss::support::Maybe<bool> has_emboss_reserved_anonymous_field_1() const;
+
+ public:
+  auto a() const -> decltype(this->emboss_reserved_anonymous_field_1().a()) {
+   return has_a().ValueOrDefault() ? emboss_reserved_anonymous_field_1().a()
+                                          : decltype(this->emboss_reserved_anonymous_field_1().a())();
+  }
+  ::emboss::support::Maybe<bool> has_a() const;
+
+ public:
+  auto b_exists() const -> decltype(this->emboss_reserved_anonymous_field_1().b_exists()) {
+   return has_b_exists().ValueOrDefault() ? emboss_reserved_anonymous_field_1().b_exists()
+                                          : decltype(this->emboss_reserved_anonymous_field_1().b_exists())();
+  }
+  ::emboss::support::Maybe<bool> has_b_exists() const;
+
+ public:
+  auto b() const -> decltype(this->emboss_reserved_anonymous_field_1().b()) {
+   return has_b().ValueOrDefault() ? emboss_reserved_anonymous_field_1().b()
+                                          : decltype(this->emboss_reserved_anonymous_field_1().b())();
+  }
+  ::emboss::support::Maybe<bool> has_b() const;
+
+ public:
+  auto b_true() const -> decltype(this->emboss_reserved_anonymous_field_1().b_true()) {
+   return has_b_true().ValueOrDefault() ? emboss_reserved_anonymous_field_1().b_true()
+                                          : decltype(this->emboss_reserved_anonymous_field_1().b_true())();
+  }
+  ::emboss::support::Maybe<bool> has_b_true() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericRequiresWithOptionalFieldsView;
+};
+using RequiresWithOptionalFieldsView =
+    GenericRequiresWithOptionalFieldsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using RequiresWithOptionalFieldsWriter =
+    GenericRequiresWithOptionalFieldsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericRequiresWithOptionalFieldsView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericRequiresWithOptionalFieldsView<
+    GenericRequiresWithOptionalFieldsView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericRequiresWithOptionalFieldsView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeRequiresWithOptionalFieldsView( T &&emboss_reserved_local_arg) {
+  return GenericRequiresWithOptionalFieldsView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericRequiresWithOptionalFieldsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeRequiresWithOptionalFieldsView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericRequiresWithOptionalFieldsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericRequiresWithOptionalFieldsView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedRequiresWithOptionalFieldsView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericRequiresWithOptionalFieldsView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+namespace RequiresInArrayElements {
+namespace Element {
+struct EmbossReservedValidatorForX {
+  template <typename ValueType>
+  static constexpr bool ValueIsOk(ValueType emboss_reserved_local_value) {
+    return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+           (::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value)), ::emboss::support::LessThanOrEqual</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL))))).ValueOrDefault();
+  }
+};
+
+
+}  // namespace Element
+
+
+
+
+
+namespace Element {
+
+}  // namespace Element
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericElementView;
+
+template <class Storage>
+class GenericElementView final {
+ public:
+  GenericElementView() : backing_() {}
+  explicit GenericElementView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericElementView(
+      const GenericElementView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericElementView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericElementView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericElementView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericElementView<Storage> &operator=(
+      const GenericElementView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericElementView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericElementView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericElementView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericElementView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericElementView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, Element::EmbossReservedValidatorForX>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericElementView;
+};
+using ElementView =
+    GenericElementView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ElementWriter =
+    GenericElementView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericElementView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericElementView<
+    GenericElementView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericElementView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeElementView( T &&emboss_reserved_local_arg) {
+  return GenericElementView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericElementView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeElementView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericElementView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericElementView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedElementView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericElementView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+}  // namespace RequiresInArrayElements
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericRequiresInArrayElementsView;
+
+template <class Storage>
+class GenericRequiresInArrayElementsView final {
+ public:
+  GenericRequiresInArrayElementsView() : backing_() {}
+  explicit GenericRequiresInArrayElementsView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericRequiresInArrayElementsView(
+      const GenericRequiresInArrayElementsView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericRequiresInArrayElementsView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericRequiresInArrayElementsView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericRequiresInArrayElementsView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericRequiresInArrayElementsView<Storage> &operator=(
+      const GenericRequiresInArrayElementsView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_xs().Known()) return false;
+    if (has_xs().ValueOrDefault() && !xs().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericRequiresInArrayElementsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_xs().Known()) return false;
+    if (!emboss_reserved_local_other.has_xs().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xs().ValueOrDefault() &&
+        !has_xs().ValueOrDefault())
+      return false;
+    if (has_xs().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xs().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xs().ValueOrDefault() &&
+        has_xs().ValueOrDefault() &&
+        !xs().Equals(emboss_reserved_local_other.xs()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericRequiresInArrayElementsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_xs().ValueOr(false) &&
+        !has_xs().ValueOr(false))
+      return false;
+    if (has_xs().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xs().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xs().ValueOr(false) &&
+        has_xs().ValueOr(false) &&
+        !xs().UncheckedEquals(emboss_reserved_local_other.xs()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericRequiresInArrayElementsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericRequiresInArrayElementsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericRequiresInArrayElementsView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "xs") {
+        if (!xs().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_xs().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xs().IsAggregate() || xs().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xs: ");
+        xs().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xs().IsAggregate() && !xs().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xs: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::test::RequiresInArrayElements::GenericElementView<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/1, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 1,
+    8 >
+
+ xs() const;
+  ::emboss::support::Maybe<bool> has_xs() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericRequiresInArrayElementsView;
+};
+using RequiresInArrayElementsView =
+    GenericRequiresInArrayElementsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using RequiresInArrayElementsWriter =
+    GenericRequiresInArrayElementsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericRequiresInArrayElementsView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericRequiresInArrayElementsView<
+    GenericRequiresInArrayElementsView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericRequiresInArrayElementsView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeRequiresInArrayElementsView( T &&emboss_reserved_local_arg) {
+  return GenericRequiresInArrayElementsView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericRequiresInArrayElementsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeRequiresInArrayElementsView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericRequiresInArrayElementsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericRequiresInArrayElementsView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedRequiresInArrayElementsView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericRequiresInArrayElementsView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace RequiresIntegers {
+
+}  // namespace RequiresIntegers
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, RequiresIntegers::EmbossReservedValidatorForZeroThroughNine>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericRequiresIntegersView<Storage>::zero_through_nine()
+    const {
+
+  if ( has_zero_through_nine().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, RequiresIntegers::EmbossReservedValidatorForZeroThroughNine>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, RequiresIntegers::EmbossReservedValidatorForZeroThroughNine>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRequiresIntegersView<Storage>::has_zero_through_nine() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, RequiresIntegers::EmbossReservedValidatorForTenThroughTwenty>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericRequiresIntegersView<Storage>::ten_through_twenty()
+    const {
+
+  if ( has_ten_through_twenty().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, RequiresIntegers::EmbossReservedValidatorForTenThroughTwenty>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, RequiresIntegers::EmbossReservedValidatorForTenThroughTwenty>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRequiresIntegersView<Storage>::has_ten_through_twenty() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, RequiresIntegers::EmbossReservedValidatorForDisjoint>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ GenericRequiresIntegersView<Storage>::disjoint()
+    const {
+
+  if ( has_disjoint().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, RequiresIntegers::EmbossReservedValidatorForDisjoint>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, RequiresIntegers::EmbossReservedValidatorForDisjoint>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRequiresIntegersView<Storage>::has_disjoint() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericRequiresIntegersView<Storage>::EmbossReservedVirtualZtnPlusTttView
+GenericRequiresIntegersView<Storage>::ztn_plus_ttt() const {
+  return
+      typename GenericRequiresIntegersView<Storage>::EmbossReservedVirtualZtnPlusTttView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRequiresIntegersView<Storage>::has_ztn_plus_ttt() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericRequiresIntegersView<Storage>::EmbossReservedVirtualAliasOfZeroThroughNineView
+GenericRequiresIntegersView<Storage>::alias_of_zero_through_nine() const {
+  return
+      typename GenericRequiresIntegersView<Storage>::EmbossReservedVirtualAliasOfZeroThroughNineView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRequiresIntegersView<Storage>::has_alias_of_zero_through_nine() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericRequiresIntegersView<Storage>::EmbossReservedVirtualZeroThroughNinePlusFiveView
+GenericRequiresIntegersView<Storage>::zero_through_nine_plus_five() const {
+  return
+      typename GenericRequiresIntegersView<Storage>::EmbossReservedVirtualZeroThroughNinePlusFiveView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRequiresIntegersView<Storage>::has_zero_through_nine_plus_five() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace RequiresIntegers {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace RequiresIntegers
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresIntegersView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return RequiresIntegers::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresIntegersView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return RequiresIntegers::IntrinsicSizeInBytes();
+}
+
+namespace RequiresIntegers {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace RequiresIntegers
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresIntegersView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return RequiresIntegers::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresIntegersView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return RequiresIntegers::MaxSizeInBytes();
+}
+
+namespace RequiresIntegers {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace RequiresIntegers
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresIntegersView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return RequiresIntegers::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresIntegersView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return RequiresIntegers::MinSizeInBytes();
+}
+namespace RequiresBools {
+namespace EmbossReservedAnonymousField2 {
+
+}  // namespace EmbossReservedAnonymousField2
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericEmbossReservedAnonymousField2View<Storage>::a()
+    const {
+
+  if ( has_a().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField2View<Storage>::has_a() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 1>>
+
+ GenericEmbossReservedAnonymousField2View<Storage>::b()
+    const {
+
+  if ( has_b().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 1>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 1>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField2View<Storage>::has_b() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, EmbossReservedAnonymousField2::EmbossReservedValidatorForMustBeTrue>,
+    typename Storage::template OffsetStorageType</**/0, 2>>
+
+ GenericEmbossReservedAnonymousField2View<Storage>::must_be_true()
+    const {
+
+  if ( has_must_be_true().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, EmbossReservedAnonymousField2::EmbossReservedValidatorForMustBeTrue>,
+    typename Storage::template OffsetStorageType</**/0, 2>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, EmbossReservedAnonymousField2::EmbossReservedValidatorForMustBeTrue>,
+    typename Storage::template OffsetStorageType</**/0, 2>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField2View<Storage>::has_must_be_true() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, EmbossReservedAnonymousField2::EmbossReservedValidatorForMustBeFalse>,
+    typename Storage::template OffsetStorageType</**/0, 3>>
+
+ GenericEmbossReservedAnonymousField2View<Storage>::must_be_false()
+    const {
+
+  if ( has_must_be_false().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, EmbossReservedAnonymousField2::EmbossReservedValidatorForMustBeFalse>,
+    typename Storage::template OffsetStorageType</**/0, 3>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   3>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, EmbossReservedAnonymousField2::EmbossReservedValidatorForMustBeFalse>,
+    typename Storage::template OffsetStorageType</**/0, 3>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField2View<Storage>::has_must_be_false() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace EmbossReservedAnonymousField2 {
+inline constexpr ::std::int32_t IntrinsicSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField2
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField2View<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField2::IntrinsicSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField2View<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField2::IntrinsicSizeInBits();
+}
+
+namespace EmbossReservedAnonymousField2 {
+inline constexpr ::std::int32_t MaxSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField2
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField2View<Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField2::MaxSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField2View<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField2::MaxSizeInBits();
+}
+
+namespace EmbossReservedAnonymousField2 {
+inline constexpr ::std::int32_t MinSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField2
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField2View<Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField2::MinSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField2View<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField2::MinSizeInBits();
+}
+
+}  // namespace RequiresBools
+
+
+template <class Storage>
+inline typename ::emboss::test::RequiresBools::GenericEmbossReservedAnonymousField2View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericRequiresBoolsView<Storage>::emboss_reserved_anonymous_field_2()
+    const {
+
+  if ( has_emboss_reserved_anonymous_field_2().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::RequiresBools::GenericEmbossReservedAnonymousField2View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::RequiresBools::GenericEmbossReservedAnonymousField2View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRequiresBoolsView<Storage>::has_emboss_reserved_anonymous_field_2() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRequiresBoolsView<Storage>::has_a() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRequiresBoolsView<Storage>::has_b() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRequiresBoolsView<Storage>::has_must_be_true() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRequiresBoolsView<Storage>::has_must_be_false() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+template <class Storage>
+inline typename GenericRequiresBoolsView<Storage>::EmbossReservedVirtualBMustBeFalseView
+GenericRequiresBoolsView<Storage>::b_must_be_false() const {
+  return
+      typename GenericRequiresBoolsView<Storage>::EmbossReservedVirtualBMustBeFalseView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRequiresBoolsView<Storage>::has_b_must_be_false() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericRequiresBoolsView<Storage>::EmbossReservedVirtualAliasOfAMustBeTrueView
+GenericRequiresBoolsView<Storage>::alias_of_a_must_be_true() const {
+  return
+      typename GenericRequiresBoolsView<Storage>::EmbossReservedVirtualAliasOfAMustBeTrueView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRequiresBoolsView<Storage>::has_alias_of_a_must_be_true() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace RequiresBools {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace RequiresBools
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresBoolsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return RequiresBools::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresBoolsView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return RequiresBools::IntrinsicSizeInBytes();
+}
+
+namespace RequiresBools {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace RequiresBools
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresBoolsView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return RequiresBools::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresBoolsView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return RequiresBools::MaxSizeInBytes();
+}
+
+namespace RequiresBools {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace RequiresBools
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresBoolsView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return RequiresBools::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresBoolsView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return RequiresBools::MinSizeInBytes();
+}
+namespace RequiresEnums {
+
+}  // namespace RequiresEnums
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::RequiresEnums::Enum,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericRequiresEnumsView<Storage>::a()
+    const {
+
+  if ( has_a().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::RequiresEnums::Enum,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::RequiresEnums::Enum,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRequiresEnumsView<Storage>::has_a() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::RequiresEnums::Enum,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericRequiresEnumsView<Storage>::b()
+    const {
+
+  if ( has_b().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::RequiresEnums::Enum,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::RequiresEnums::Enum,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRequiresEnumsView<Storage>::has_b() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::RequiresEnums::Enum,
+    ::emboss::support::FixedSizeViewParameters<8, RequiresEnums::EmbossReservedValidatorForC>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ GenericRequiresEnumsView<Storage>::c()
+    const {
+
+  if ( has_c().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::RequiresEnums::Enum,
+    ::emboss::support::FixedSizeViewParameters<8, RequiresEnums::EmbossReservedValidatorForC>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::RequiresEnums::Enum,
+    ::emboss::support::FixedSizeViewParameters<8, RequiresEnums::EmbossReservedValidatorForC>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRequiresEnumsView<Storage>::has_c() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericRequiresEnumsView<Storage>::EmbossReservedVirtualFilteredAView
+GenericRequiresEnumsView<Storage>::filtered_a() const {
+  return
+      typename GenericRequiresEnumsView<Storage>::EmbossReservedVirtualFilteredAView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRequiresEnumsView<Storage>::has_filtered_a() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericRequiresEnumsView<Storage>::EmbossReservedVirtualAliasOfAView
+GenericRequiresEnumsView<Storage>::alias_of_a() const {
+  return
+      typename GenericRequiresEnumsView<Storage>::EmbossReservedVirtualAliasOfAView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRequiresEnumsView<Storage>::has_alias_of_a() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace RequiresEnums {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace RequiresEnums
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresEnumsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return RequiresEnums::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresEnumsView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return RequiresEnums::IntrinsicSizeInBytes();
+}
+
+namespace RequiresEnums {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace RequiresEnums
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresEnumsView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return RequiresEnums::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresEnumsView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return RequiresEnums::MaxSizeInBytes();
+}
+
+namespace RequiresEnums {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace RequiresEnums
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresEnumsView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return RequiresEnums::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresEnumsView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return RequiresEnums::MinSizeInBytes();
+}
+namespace RequiresWithOptionalFields {
+namespace EmbossReservedAnonymousField1 {
+
+}  // namespace EmbossReservedAnonymousField1
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericEmbossReservedAnonymousField1View<Storage>::a()
+    const {
+
+  if ( has_a().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField1View<Storage>::has_a() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 1>>
+
+ GenericEmbossReservedAnonymousField1View<Storage>::b_exists()
+    const {
+
+  if ( has_b_exists().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 1>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 1>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField1View<Storage>::has_b_exists() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 2>>
+
+ GenericEmbossReservedAnonymousField1View<Storage>::b()
+    const {
+
+  if ( has_b().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 2>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 2>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField1View<Storage>::has_b() const {
+  return (b_exists().Ok()    ? ::emboss::support::Maybe</**/bool>(static_cast</**/bool>(b_exists().UncheckedRead()))    : ::emboss::support::Maybe</**/bool>());
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, EmbossReservedAnonymousField1::EmbossReservedValidatorForBTrue>,
+    typename Storage::template OffsetStorageType</**/0, 2>>
+
+ GenericEmbossReservedAnonymousField1View<Storage>::b_true()
+    const {
+
+  if ( has_b_true().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, EmbossReservedAnonymousField1::EmbossReservedValidatorForBTrue>,
+    typename Storage::template OffsetStorageType</**/0, 2>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::FlagView<
+    /**/ ::emboss::support::FixedSizeViewParameters<1, EmbossReservedAnonymousField1::EmbossReservedValidatorForBTrue>,
+    typename Storage::template OffsetStorageType</**/0, 2>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField1View<Storage>::has_b_true() const {
+  return (b_exists().Ok()    ? ::emboss::support::Maybe</**/bool>(static_cast</**/bool>(b_exists().UncheckedRead()))    : ::emboss::support::Maybe</**/bool>());
+}
+
+
+template <class Storage>
+inline typename GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView
+GenericEmbossReservedAnonymousField1View<Storage>::IntrinsicSizeInBits() const {
+  return
+      typename GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField1View<Storage>::has_IntrinsicSizeInBits() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace EmbossReservedAnonymousField1 {
+inline constexpr ::std::int32_t MaxSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField1
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField1::MaxSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField1::MaxSizeInBits();
+}
+
+namespace EmbossReservedAnonymousField1 {
+inline constexpr ::std::int32_t MinSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField1
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField1::MinSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField1::MinSizeInBits();
+}
+
+}  // namespace RequiresWithOptionalFields
+
+
+template <class Storage>
+inline typename ::emboss::test::RequiresWithOptionalFields::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericRequiresWithOptionalFieldsView<Storage>::emboss_reserved_anonymous_field_1()
+    const {
+
+  if ( has_emboss_reserved_anonymous_field_1().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::RequiresWithOptionalFields::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::RequiresWithOptionalFields::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRequiresWithOptionalFieldsView<Storage>::has_emboss_reserved_anonymous_field_1() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRequiresWithOptionalFieldsView<Storage>::has_a() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRequiresWithOptionalFieldsView<Storage>::has_b_exists() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRequiresWithOptionalFieldsView<Storage>::has_b() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_anonymous_field_1().has_b());
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRequiresWithOptionalFieldsView<Storage>::has_b_true() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_anonymous_field_1().has_b_true());
+}
+
+
+namespace RequiresWithOptionalFields {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace RequiresWithOptionalFields
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresWithOptionalFieldsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return RequiresWithOptionalFields::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresWithOptionalFieldsView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return RequiresWithOptionalFields::IntrinsicSizeInBytes();
+}
+
+namespace RequiresWithOptionalFields {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace RequiresWithOptionalFields
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresWithOptionalFieldsView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return RequiresWithOptionalFields::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresWithOptionalFieldsView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return RequiresWithOptionalFields::MaxSizeInBytes();
+}
+
+namespace RequiresWithOptionalFields {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace RequiresWithOptionalFields
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresWithOptionalFieldsView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return RequiresWithOptionalFields::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresWithOptionalFieldsView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return RequiresWithOptionalFields::MinSizeInBytes();
+}
+namespace RequiresInArrayElements {
+namespace Element {
+
+}  // namespace Element
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, Element::EmbossReservedValidatorForX>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericElementView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, Element::EmbossReservedValidatorForX>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, Element::EmbossReservedValidatorForX>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericElementView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Element {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace Element
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericElementView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Element::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericElementView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Element::IntrinsicSizeInBytes();
+}
+
+namespace Element {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace Element
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericElementView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Element::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericElementView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Element::MaxSizeInBytes();
+}
+
+namespace Element {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace Element
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericElementView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Element::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericElementView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Element::MinSizeInBytes();
+}
+
+}  // namespace RequiresInArrayElements
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::test::RequiresInArrayElements::GenericElementView<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/1, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 1,
+    8 >
+
+ GenericRequiresInArrayElementsView<Storage>::xs()
+    const {
+
+  if ( has_xs().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::test::RequiresInArrayElements::GenericElementView<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/1, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 1,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::test::RequiresInArrayElements::GenericElementView<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/1, 0>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 1,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRequiresInArrayElementsView<Storage>::has_xs() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace RequiresInArrayElements {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace RequiresInArrayElements
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresInArrayElementsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return RequiresInArrayElements::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresInArrayElementsView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return RequiresInArrayElements::IntrinsicSizeInBytes();
+}
+
+namespace RequiresInArrayElements {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace RequiresInArrayElements
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresInArrayElementsView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return RequiresInArrayElements::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresInArrayElementsView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return RequiresInArrayElements::MaxSizeInBytes();
+}
+
+namespace RequiresInArrayElements {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace RequiresInArrayElements
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresInArrayElementsView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return RequiresInArrayElements::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRequiresInArrayElementsView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return RequiresInArrayElements::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_REQUIRES_EMB_H_
+
diff --git a/testdata/golden_cpp/start_size_range.emb.h b/testdata/golden_cpp/start_size_range.emb.h
new file mode 100644
index 0000000..d9f0166
--- /dev/null
+++ b/testdata/golden_cpp/start_size_range.emb.h
@@ -0,0 +1,992 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_START_SIZE_RANGE_EMB_H_
+#define TESTDATA_START_SIZE_RANGE_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace StartSize {
+
+}  // namespace StartSize
+
+
+template <class Storage>
+class GenericStartSizeView;
+
+
+
+
+
+
+
+
+namespace StartSize {
+
+}  // namespace StartSize
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericStartSizeView;
+
+template <class Storage>
+class GenericStartSizeView final {
+ public:
+  GenericStartSizeView() : backing_() {}
+  explicit GenericStartSizeView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStartSizeView(
+      const GenericStartSizeView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericStartSizeView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericStartSizeView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericStartSizeView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStartSizeView<Storage> &operator=(
+      const GenericStartSizeView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_size().Known()) return false;
+    if (has_size().ValueOrDefault() && !size().Ok()) return false;
+
+
+    if (!has_start_size_constants().Known()) return false;
+    if (has_start_size_constants().ValueOrDefault() && !start_size_constants().Ok()) return false;
+
+
+    if (!has_payload().Known()) return false;
+    if (has_payload().ValueOrDefault() && !payload().Ok()) return false;
+
+
+    if (!has_counter().Known()) return false;
+    if (has_counter().ValueOrDefault() && !counter().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericStartSizeView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_size().Known()) return false;
+    if (!emboss_reserved_local_other.has_size().Known()) return false;
+
+    if (emboss_reserved_local_other.has_size().ValueOrDefault() &&
+        !has_size().ValueOrDefault())
+      return false;
+    if (has_size().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_size().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_size().ValueOrDefault() &&
+        has_size().ValueOrDefault() &&
+        !size().Equals(emboss_reserved_local_other.size()))
+      return false;
+
+
+
+    if (!has_start_size_constants().Known()) return false;
+    if (!emboss_reserved_local_other.has_start_size_constants().Known()) return false;
+
+    if (emboss_reserved_local_other.has_start_size_constants().ValueOrDefault() &&
+        !has_start_size_constants().ValueOrDefault())
+      return false;
+    if (has_start_size_constants().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_start_size_constants().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_start_size_constants().ValueOrDefault() &&
+        has_start_size_constants().ValueOrDefault() &&
+        !start_size_constants().Equals(emboss_reserved_local_other.start_size_constants()))
+      return false;
+
+
+
+    if (!has_payload().Known()) return false;
+    if (!emboss_reserved_local_other.has_payload().Known()) return false;
+
+    if (emboss_reserved_local_other.has_payload().ValueOrDefault() &&
+        !has_payload().ValueOrDefault())
+      return false;
+    if (has_payload().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_payload().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_payload().ValueOrDefault() &&
+        has_payload().ValueOrDefault() &&
+        !payload().Equals(emboss_reserved_local_other.payload()))
+      return false;
+
+
+
+    if (!has_counter().Known()) return false;
+    if (!emboss_reserved_local_other.has_counter().Known()) return false;
+
+    if (emboss_reserved_local_other.has_counter().ValueOrDefault() &&
+        !has_counter().ValueOrDefault())
+      return false;
+    if (has_counter().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_counter().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_counter().ValueOrDefault() &&
+        has_counter().ValueOrDefault() &&
+        !counter().Equals(emboss_reserved_local_other.counter()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericStartSizeView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_size().ValueOr(false) &&
+        !has_size().ValueOr(false))
+      return false;
+    if (has_size().ValueOr(false) &&
+        !emboss_reserved_local_other.has_size().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_size().ValueOr(false) &&
+        has_size().ValueOr(false) &&
+        !size().UncheckedEquals(emboss_reserved_local_other.size()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_start_size_constants().ValueOr(false) &&
+        !has_start_size_constants().ValueOr(false))
+      return false;
+    if (has_start_size_constants().ValueOr(false) &&
+        !emboss_reserved_local_other.has_start_size_constants().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_start_size_constants().ValueOr(false) &&
+        has_start_size_constants().ValueOr(false) &&
+        !start_size_constants().UncheckedEquals(emboss_reserved_local_other.start_size_constants()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_payload().ValueOr(false) &&
+        !has_payload().ValueOr(false))
+      return false;
+    if (has_payload().ValueOr(false) &&
+        !emboss_reserved_local_other.has_payload().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_payload().ValueOr(false) &&
+        has_payload().ValueOr(false) &&
+        !payload().UncheckedEquals(emboss_reserved_local_other.payload()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_counter().ValueOr(false) &&
+        !has_counter().ValueOr(false))
+      return false;
+    if (has_counter().ValueOr(false) &&
+        !emboss_reserved_local_other.has_counter().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_counter().ValueOr(false) &&
+        has_counter().ValueOr(false) &&
+        !counter().UncheckedEquals(emboss_reserved_local_other.counter()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericStartSizeView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericStartSizeView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericStartSizeView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "size") {
+        if (!size().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "start_size_constants") {
+        if (!start_size_constants().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "payload") {
+        if (!payload().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "counter") {
+        if (!counter().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_size().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          size().IsAggregate() || size().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("size: ");
+        size().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !size().IsAggregate() && !size().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# size: UNREADABLE\n");
+      }
+    }
+
+    if (has_start_size_constants().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          start_size_constants().IsAggregate() || start_size_constants().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("start_size_constants: ");
+        start_size_constants().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !start_size_constants().IsAggregate() && !start_size_constants().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# start_size_constants: UNREADABLE\n");
+      }
+    }
+
+    if (has_payload().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          payload().IsAggregate() || payload().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("payload: ");
+        payload().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !payload().IsAggregate() && !payload().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# payload: UNREADABLE\n");
+      }
+    }
+
+    if (has_counter().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          counter().IsAggregate() || counter().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("counter: ");
+        counter().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !counter().IsAggregate() && !counter().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# counter: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ size() const;
+  ::emboss::support::Maybe<bool> has_size() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+ start_size_constants() const;
+  ::emboss::support::Maybe<bool> has_start_size_constants() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+ payload() const;
+  ::emboss::support::Maybe<bool> has_payload() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 32>>
+
+ counter() const;
+  ::emboss::support::Maybe<bool> has_counter() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericStartSizeView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.size();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)), emboss_reserved_local_subexpr_2);
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)));
+      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_5, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)), emboss_reserved_local_subexpr_4, emboss_reserved_local_subexpr_6);
+
+      return emboss_reserved_local_subexpr_7;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericStartSizeView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericStartSizeView;
+};
+using StartSizeView =
+    GenericStartSizeView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using StartSizeWriter =
+    GenericStartSizeView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericStartSizeView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericStartSizeView<
+    GenericStartSizeView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericStartSizeView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeStartSizeView( T &&emboss_reserved_local_arg) {
+  return GenericStartSizeView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericStartSizeView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeStartSizeView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericStartSizeView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericStartSizeView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedStartSizeView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericStartSizeView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace StartSize {
+
+}  // namespace StartSize
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericStartSizeView<Storage>::size()
+    const {
+
+  if ( has_size().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStartSizeView<Storage>::has_size() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+ GenericStartSizeView<Storage>::start_size_constants()
+    const {
+
+  if ( has_start_size_constants().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStartSizeView<Storage>::has_start_size_constants() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+ GenericStartSizeView<Storage>::payload()
+    const {
+
+  if ( has_payload().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = size();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_2;
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   3>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 3>, 1,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStartSizeView<Storage>::has_payload() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 32>>
+
+ GenericStartSizeView<Storage>::counter()
+    const {
+
+  if ( has_counter().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = size();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+    const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)), emboss_reserved_local_subexpr_2);
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_3;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStartSizeView<Storage>::has_counter() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericStartSizeView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericStartSizeView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericStartSizeView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStartSizeView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace StartSize {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(262LL)).ValueOrDefault();
+}
+}  // namespace StartSize
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStartSizeView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return StartSize::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStartSizeView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return StartSize::MaxSizeInBytes();
+}
+
+namespace StartSize {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(7LL)).ValueOrDefault();
+}
+}  // namespace StartSize
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStartSizeView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return StartSize::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStartSizeView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return StartSize::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_START_SIZE_RANGE_EMB_H_
+
diff --git a/testdata/golden_cpp/subtypes.emb.h b/testdata/golden_cpp/subtypes.emb.h
new file mode 100644
index 0000000..860d554
--- /dev/null
+++ b/testdata/golden_cpp/subtypes.emb.h
@@ -0,0 +1,3920 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_SUBTYPES_EMB_H_
+#define TESTDATA_SUBTYPES_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace Out {
+namespace In {
+namespace InIn {
+enum class InInIn : ::std::uint64_t;
+
+
+}  // namespace InIn
+
+
+template <class Storage>
+class GenericInInView;
+
+
+}  // namespace In
+
+
+template <class Storage>
+class GenericInView;
+
+
+namespace In2 {
+
+}  // namespace In2
+
+
+template <class Storage>
+class GenericIn2View;
+
+
+}  // namespace Out
+
+
+template <class Storage>
+class GenericOutView;
+
+
+
+
+
+
+
+
+
+
+
+
+namespace Out {
+
+
+
+
+
+
+
+
+namespace In {
+
+
+
+
+
+namespace InIn {
+enum class InInIn : ::std::uint64_t {
+  NO = static_cast</**/::std::int32_t>(0LL),
+  YES = static_cast</**/::std::int32_t>(1LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<InInIn> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   InInIn *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("NO", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = InInIn::NO;
+      return true;
+    }
+
+    if (!strcmp("YES", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = InInIn::YES;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      InInIn emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case InInIn::NO: return "NO";
+
+      case InInIn::YES: return "YES";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(InInIn emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case InInIn::NO: return true;
+
+      case InInIn::YES: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       InInIn emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<InInIn>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    InInIn *emboss_reserved_local_result) {
+  return EnumTraits<InInIn>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    InInIn emboss_reserved_local_value) {
+  return EnumTraits<InInIn>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(InInIn emboss_reserved_local_value) {
+  return EnumTraits<InInIn>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    InInIn emboss_reserved_local_value) {
+  return EnumTraits<InInIn>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+
+}  // namespace InIn
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericInInView;
+
+template <class Storage>
+class GenericInInView final {
+ public:
+  GenericInInView() : backing_() {}
+  explicit GenericInInView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericInInView(
+      const GenericInInView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericInInView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericInInView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericInInView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericInInView<Storage> &operator=(
+      const GenericInInView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+    using InInIn = ::emboss::test::Out::In::InIn::InInIn;
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_outer_offset().Known()) return false;
+    if (has_outer_offset().ValueOrDefault() && !outer_offset().Ok()) return false;
+
+
+    if (!has_field_enum().Known()) return false;
+    if (has_field_enum().ValueOrDefault() && !field_enum().Ok()) return false;
+
+
+    if (!has_in_2().Known()) return false;
+    if (has_in_2().ValueOrDefault() && !in_2().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericInInView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_field_enum().Known()) return false;
+    if (!emboss_reserved_local_other.has_field_enum().Known()) return false;
+
+    if (emboss_reserved_local_other.has_field_enum().ValueOrDefault() &&
+        !has_field_enum().ValueOrDefault())
+      return false;
+    if (has_field_enum().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_field_enum().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_field_enum().ValueOrDefault() &&
+        has_field_enum().ValueOrDefault() &&
+        !field_enum().Equals(emboss_reserved_local_other.field_enum()))
+      return false;
+
+
+
+    if (!has_in_2().Known()) return false;
+    if (!emboss_reserved_local_other.has_in_2().Known()) return false;
+
+    if (emboss_reserved_local_other.has_in_2().ValueOrDefault() &&
+        !has_in_2().ValueOrDefault())
+      return false;
+    if (has_in_2().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_in_2().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_in_2().ValueOrDefault() &&
+        has_in_2().ValueOrDefault() &&
+        !in_2().Equals(emboss_reserved_local_other.in_2()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericInInView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_field_enum().ValueOr(false) &&
+        !has_field_enum().ValueOr(false))
+      return false;
+    if (has_field_enum().ValueOr(false) &&
+        !emboss_reserved_local_other.has_field_enum().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_field_enum().ValueOr(false) &&
+        has_field_enum().ValueOr(false) &&
+        !field_enum().UncheckedEquals(emboss_reserved_local_other.field_enum()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_in_2().ValueOr(false) &&
+        !has_in_2().ValueOr(false))
+      return false;
+    if (has_in_2().ValueOr(false) &&
+        !emboss_reserved_local_other.has_in_2().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_in_2().ValueOr(false) &&
+        has_in_2().ValueOr(false) &&
+        !in_2().UncheckedEquals(emboss_reserved_local_other.in_2()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericInInView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericInInView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericInInView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "field_enum") {
+        if (!field_enum().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "in_2") {
+        if (!in_2().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_outer_offset().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          outer_offset().IsAggregate() || outer_offset().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# outer_offset: ");
+        outer_offset().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# outer_offset: UNREADABLE\n");
+      }
+    }
+
+    if (has_field_enum().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          field_enum().IsAggregate() || field_enum().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("field_enum: ");
+        field_enum().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !field_enum().IsAggregate() && !field_enum().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# field_enum: UNREADABLE\n");
+      }
+    }
+
+    if (has_in_2().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          in_2().IsAggregate() || in_2().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("in_2: ");
+        in_2().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !in_2().IsAggregate() && !in_2().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# in_2: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  class EmbossReservedVirtualOuterOffsetView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedVirtualOuterOffsetView() {}
+    EmbossReservedVirtualOuterOffsetView(const EmbossReservedVirtualOuterOffsetView &) = default;
+    EmbossReservedVirtualOuterOffsetView(EmbossReservedVirtualOuterOffsetView &&) = default;
+    EmbossReservedVirtualOuterOffsetView &operator=(const EmbossReservedVirtualOuterOffsetView &) =
+        default;
+    EmbossReservedVirtualOuterOffsetView &operator=(EmbossReservedVirtualOuterOffsetView &&) =
+        default;
+    ~EmbossReservedVirtualOuterOffsetView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedVirtualOuterOffsetView outer_offset() {
+    return EmbossReservedVirtualOuterOffsetView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_outer_offset() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Out::In::InIn::InInIn,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ field_enum() const;
+  ::emboss::support::Maybe<bool> has_field_enum() const;
+
+ public:
+  typename ::emboss::test::Out::GenericIn2View<typename Storage::template OffsetStorageType</**/0, 1>>
+
+ in_2() const;
+  ::emboss::support::Maybe<bool> has_in_2() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericInInView;
+};
+using InInView =
+    GenericInInView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using InInWriter =
+    GenericInInView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericInInView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericInInView<
+    GenericInInView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericInInView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeInInView( T &&emboss_reserved_local_arg) {
+  return GenericInInView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericInInView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeInInView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericInInView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericInInView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedInInView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericInInView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+}  // namespace In
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericInView;
+
+template <class Storage>
+class GenericInView final {
+ public:
+  GenericInView() : backing_() {}
+  explicit GenericInView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericInView(
+      const GenericInView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericInView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericInView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericInView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericInView<Storage> &operator=(
+      const GenericInView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_in_in_1().Known()) return false;
+    if (has_in_in_1().ValueOrDefault() && !in_in_1().Ok()) return false;
+
+
+    if (!has_in_in_2().Known()) return false;
+    if (has_in_in_2().ValueOrDefault() && !in_in_2().Ok()) return false;
+
+
+    if (!has_in_in_in_1().Known()) return false;
+    if (has_in_in_in_1().ValueOrDefault() && !in_in_in_1().Ok()) return false;
+
+
+    if (!has_in_2().Known()) return false;
+    if (has_in_2().ValueOrDefault() && !in_2().Ok()) return false;
+
+
+    if (!has_name_collision().Known()) return false;
+    if (has_name_collision().ValueOrDefault() && !name_collision().Ok()) return false;
+
+
+    if (!has_name_collision_check().Known()) return false;
+    if (has_name_collision_check().ValueOrDefault() && !name_collision_check().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericInView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_in_in_1().Known()) return false;
+    if (!emboss_reserved_local_other.has_in_in_1().Known()) return false;
+
+    if (emboss_reserved_local_other.has_in_in_1().ValueOrDefault() &&
+        !has_in_in_1().ValueOrDefault())
+      return false;
+    if (has_in_in_1().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_in_in_1().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_in_in_1().ValueOrDefault() &&
+        has_in_in_1().ValueOrDefault() &&
+        !in_in_1().Equals(emboss_reserved_local_other.in_in_1()))
+      return false;
+
+
+
+    if (!has_in_in_2().Known()) return false;
+    if (!emboss_reserved_local_other.has_in_in_2().Known()) return false;
+
+    if (emboss_reserved_local_other.has_in_in_2().ValueOrDefault() &&
+        !has_in_in_2().ValueOrDefault())
+      return false;
+    if (has_in_in_2().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_in_in_2().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_in_in_2().ValueOrDefault() &&
+        has_in_in_2().ValueOrDefault() &&
+        !in_in_2().Equals(emboss_reserved_local_other.in_in_2()))
+      return false;
+
+
+
+    if (!has_in_in_in_1().Known()) return false;
+    if (!emboss_reserved_local_other.has_in_in_in_1().Known()) return false;
+
+    if (emboss_reserved_local_other.has_in_in_in_1().ValueOrDefault() &&
+        !has_in_in_in_1().ValueOrDefault())
+      return false;
+    if (has_in_in_in_1().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_in_in_in_1().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_in_in_in_1().ValueOrDefault() &&
+        has_in_in_in_1().ValueOrDefault() &&
+        !in_in_in_1().Equals(emboss_reserved_local_other.in_in_in_1()))
+      return false;
+
+
+
+    if (!has_in_2().Known()) return false;
+    if (!emboss_reserved_local_other.has_in_2().Known()) return false;
+
+    if (emboss_reserved_local_other.has_in_2().ValueOrDefault() &&
+        !has_in_2().ValueOrDefault())
+      return false;
+    if (has_in_2().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_in_2().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_in_2().ValueOrDefault() &&
+        has_in_2().ValueOrDefault() &&
+        !in_2().Equals(emboss_reserved_local_other.in_2()))
+      return false;
+
+
+
+    if (!has_name_collision().Known()) return false;
+    if (!emboss_reserved_local_other.has_name_collision().Known()) return false;
+
+    if (emboss_reserved_local_other.has_name_collision().ValueOrDefault() &&
+        !has_name_collision().ValueOrDefault())
+      return false;
+    if (has_name_collision().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_name_collision().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_name_collision().ValueOrDefault() &&
+        has_name_collision().ValueOrDefault() &&
+        !name_collision().Equals(emboss_reserved_local_other.name_collision()))
+      return false;
+
+
+
+    if (!has_name_collision_check().Known()) return false;
+    if (!emboss_reserved_local_other.has_name_collision_check().Known()) return false;
+
+    if (emboss_reserved_local_other.has_name_collision_check().ValueOrDefault() &&
+        !has_name_collision_check().ValueOrDefault())
+      return false;
+    if (has_name_collision_check().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_name_collision_check().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_name_collision_check().ValueOrDefault() &&
+        has_name_collision_check().ValueOrDefault() &&
+        !name_collision_check().Equals(emboss_reserved_local_other.name_collision_check()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericInView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_in_in_1().ValueOr(false) &&
+        !has_in_in_1().ValueOr(false))
+      return false;
+    if (has_in_in_1().ValueOr(false) &&
+        !emboss_reserved_local_other.has_in_in_1().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_in_in_1().ValueOr(false) &&
+        has_in_in_1().ValueOr(false) &&
+        !in_in_1().UncheckedEquals(emboss_reserved_local_other.in_in_1()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_in_in_2().ValueOr(false) &&
+        !has_in_in_2().ValueOr(false))
+      return false;
+    if (has_in_in_2().ValueOr(false) &&
+        !emboss_reserved_local_other.has_in_in_2().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_in_in_2().ValueOr(false) &&
+        has_in_in_2().ValueOr(false) &&
+        !in_in_2().UncheckedEquals(emboss_reserved_local_other.in_in_2()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_in_in_in_1().ValueOr(false) &&
+        !has_in_in_in_1().ValueOr(false))
+      return false;
+    if (has_in_in_in_1().ValueOr(false) &&
+        !emboss_reserved_local_other.has_in_in_in_1().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_in_in_in_1().ValueOr(false) &&
+        has_in_in_in_1().ValueOr(false) &&
+        !in_in_in_1().UncheckedEquals(emboss_reserved_local_other.in_in_in_1()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_in_2().ValueOr(false) &&
+        !has_in_2().ValueOr(false))
+      return false;
+    if (has_in_2().ValueOr(false) &&
+        !emboss_reserved_local_other.has_in_2().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_in_2().ValueOr(false) &&
+        has_in_2().ValueOr(false) &&
+        !in_2().UncheckedEquals(emboss_reserved_local_other.in_2()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_name_collision().ValueOr(false) &&
+        !has_name_collision().ValueOr(false))
+      return false;
+    if (has_name_collision().ValueOr(false) &&
+        !emboss_reserved_local_other.has_name_collision().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_name_collision().ValueOr(false) &&
+        has_name_collision().ValueOr(false) &&
+        !name_collision().UncheckedEquals(emboss_reserved_local_other.name_collision()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_name_collision_check().ValueOr(false) &&
+        !has_name_collision_check().ValueOr(false))
+      return false;
+    if (has_name_collision_check().ValueOr(false) &&
+        !emboss_reserved_local_other.has_name_collision_check().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_name_collision_check().ValueOr(false) &&
+        has_name_collision_check().ValueOr(false) &&
+        !name_collision_check().UncheckedEquals(emboss_reserved_local_other.name_collision_check()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericInView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericInView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericInView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "in_in_1") {
+        if (!in_in_1().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "in_in_2") {
+        if (!in_in_2().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "in_in_in_1") {
+        if (!in_in_in_1().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "in_2") {
+        if (!in_2().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "name_collision") {
+        if (!name_collision().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "name_collision_check") {
+        if (!name_collision_check().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_in_in_1().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          in_in_1().IsAggregate() || in_in_1().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("in_in_1: ");
+        in_in_1().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !in_in_1().IsAggregate() && !in_in_1().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# in_in_1: UNREADABLE\n");
+      }
+    }
+
+    if (has_in_in_2().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          in_in_2().IsAggregate() || in_in_2().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("in_in_2: ");
+        in_in_2().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !in_in_2().IsAggregate() && !in_in_2().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# in_in_2: UNREADABLE\n");
+      }
+    }
+
+    if (has_in_in_in_1().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          in_in_in_1().IsAggregate() || in_in_in_1().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("in_in_in_1: ");
+        in_in_in_1().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !in_in_in_1().IsAggregate() && !in_in_in_1().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# in_in_in_1: UNREADABLE\n");
+      }
+    }
+
+    if (has_in_2().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          in_2().IsAggregate() || in_2().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("in_2: ");
+        in_2().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !in_2().IsAggregate() && !in_2().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# in_2: UNREADABLE\n");
+      }
+    }
+
+    if (has_name_collision().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          name_collision().IsAggregate() || name_collision().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("name_collision: ");
+        name_collision().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !name_collision().IsAggregate() && !name_collision().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# name_collision: UNREADABLE\n");
+      }
+    }
+
+    if (has_name_collision_check().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          name_collision_check().IsAggregate() || name_collision_check().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("name_collision_check: ");
+        name_collision_check().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !name_collision_check().IsAggregate() && !name_collision_check().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# name_collision_check: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::test::Out::In::GenericInInView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ in_in_1() const;
+  ::emboss::support::Maybe<bool> has_in_in_1() const;
+
+ public:
+  typename ::emboss::test::Out::In::GenericInInView<typename Storage::template OffsetStorageType</**/0, 2>>
+
+ in_in_2() const;
+  ::emboss::support::Maybe<bool> has_in_in_2() const;
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Out::In::InIn::InInIn,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 8>>
+
+ in_in_in_1() const;
+  ::emboss::support::Maybe<bool> has_in_in_in_1() const;
+
+ public:
+  typename ::emboss::test::Out::GenericIn2View<typename Storage::template OffsetStorageType</**/0, 5>>
+
+ in_2() const;
+  ::emboss::support::Maybe<bool> has_in_2() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 8>>
+
+ name_collision() const;
+  ::emboss::support::Maybe<bool> has_name_collision() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+ name_collision_check() const;
+  ::emboss::support::Maybe<bool> has_name_collision_check() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericInView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.name_collision();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(7LL)), emboss_reserved_local_subexpr_4);
+
+      return emboss_reserved_local_subexpr_5;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericInView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericInView;
+};
+using InView =
+    GenericInView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using InWriter =
+    GenericInView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericInView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericInView<
+    GenericInView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericInView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeInView( T &&emboss_reserved_local_arg) {
+  return GenericInView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericInView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeInView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericInView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericInView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedInView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericInView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace In2 {
+
+}  // namespace In2
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericIn2View;
+
+template <class Storage>
+class GenericIn2View final {
+ public:
+  GenericIn2View() : backing_() {}
+  explicit GenericIn2View(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericIn2View(
+      const GenericIn2View<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericIn2View<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericIn2View(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericIn2View(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericIn2View<Storage> &operator=(
+      const GenericIn2View<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_field_byte().Known()) return false;
+    if (has_field_byte().ValueOrDefault() && !field_byte().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericIn2View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_field_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_field_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_field_byte().ValueOrDefault() &&
+        !has_field_byte().ValueOrDefault())
+      return false;
+    if (has_field_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_field_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_field_byte().ValueOrDefault() &&
+        has_field_byte().ValueOrDefault() &&
+        !field_byte().Equals(emboss_reserved_local_other.field_byte()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericIn2View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_field_byte().ValueOr(false) &&
+        !has_field_byte().ValueOr(false))
+      return false;
+    if (has_field_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_field_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_field_byte().ValueOr(false) &&
+        has_field_byte().ValueOr(false) &&
+        !field_byte().UncheckedEquals(emboss_reserved_local_other.field_byte()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericIn2View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericIn2View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericIn2View<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "field_byte") {
+        if (!field_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_field_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          field_byte().IsAggregate() || field_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("field_byte: ");
+        field_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !field_byte().IsAggregate() && !field_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# field_byte: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ field_byte() const;
+  ::emboss::support::Maybe<bool> has_field_byte() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericIn2View;
+};
+using In2View =
+    GenericIn2View</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using In2Writer =
+    GenericIn2View</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericIn2View {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericIn2View<
+    GenericIn2View<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericIn2View<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeIn2View( T &&emboss_reserved_local_arg) {
+  return GenericIn2View<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericIn2View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeIn2View( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericIn2View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericIn2View<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedIn2View(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericIn2View<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+}  // namespace Out
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericOutView;
+
+template <class Storage>
+class GenericOutView final {
+ public:
+  GenericOutView() : backing_() {}
+  explicit GenericOutView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericOutView(
+      const GenericOutView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericOutView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericOutView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericOutView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericOutView<Storage> &operator=(
+      const GenericOutView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_in_1().Known()) return false;
+    if (has_in_1().ValueOrDefault() && !in_1().Ok()) return false;
+
+
+    if (!has_in_2().Known()) return false;
+    if (has_in_2().ValueOrDefault() && !in_2().Ok()) return false;
+
+
+    if (!has_in_in_1().Known()) return false;
+    if (has_in_in_1().ValueOrDefault() && !in_in_1().Ok()) return false;
+
+
+    if (!has_in_in_2().Known()) return false;
+    if (has_in_in_2().ValueOrDefault() && !in_in_2().Ok()) return false;
+
+
+    if (!has_in_in_in_1().Known()) return false;
+    if (has_in_in_in_1().ValueOrDefault() && !in_in_in_1().Ok()) return false;
+
+
+    if (!has_in_in_in_2().Known()) return false;
+    if (has_in_in_in_2().ValueOrDefault() && !in_in_in_2().Ok()) return false;
+
+
+    if (!has_name_collision().Known()) return false;
+    if (has_name_collision().ValueOrDefault() && !name_collision().Ok()) return false;
+
+
+    if (!has_nested_constant_check().Known()) return false;
+    if (has_nested_constant_check().ValueOrDefault() && !nested_constant_check().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericOutView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_in_1().Known()) return false;
+    if (!emboss_reserved_local_other.has_in_1().Known()) return false;
+
+    if (emboss_reserved_local_other.has_in_1().ValueOrDefault() &&
+        !has_in_1().ValueOrDefault())
+      return false;
+    if (has_in_1().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_in_1().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_in_1().ValueOrDefault() &&
+        has_in_1().ValueOrDefault() &&
+        !in_1().Equals(emboss_reserved_local_other.in_1()))
+      return false;
+
+
+
+    if (!has_in_2().Known()) return false;
+    if (!emboss_reserved_local_other.has_in_2().Known()) return false;
+
+    if (emboss_reserved_local_other.has_in_2().ValueOrDefault() &&
+        !has_in_2().ValueOrDefault())
+      return false;
+    if (has_in_2().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_in_2().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_in_2().ValueOrDefault() &&
+        has_in_2().ValueOrDefault() &&
+        !in_2().Equals(emboss_reserved_local_other.in_2()))
+      return false;
+
+
+
+    if (!has_in_in_1().Known()) return false;
+    if (!emboss_reserved_local_other.has_in_in_1().Known()) return false;
+
+    if (emboss_reserved_local_other.has_in_in_1().ValueOrDefault() &&
+        !has_in_in_1().ValueOrDefault())
+      return false;
+    if (has_in_in_1().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_in_in_1().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_in_in_1().ValueOrDefault() &&
+        has_in_in_1().ValueOrDefault() &&
+        !in_in_1().Equals(emboss_reserved_local_other.in_in_1()))
+      return false;
+
+
+
+    if (!has_in_in_2().Known()) return false;
+    if (!emboss_reserved_local_other.has_in_in_2().Known()) return false;
+
+    if (emboss_reserved_local_other.has_in_in_2().ValueOrDefault() &&
+        !has_in_in_2().ValueOrDefault())
+      return false;
+    if (has_in_in_2().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_in_in_2().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_in_in_2().ValueOrDefault() &&
+        has_in_in_2().ValueOrDefault() &&
+        !in_in_2().Equals(emboss_reserved_local_other.in_in_2()))
+      return false;
+
+
+
+    if (!has_in_in_in_1().Known()) return false;
+    if (!emboss_reserved_local_other.has_in_in_in_1().Known()) return false;
+
+    if (emboss_reserved_local_other.has_in_in_in_1().ValueOrDefault() &&
+        !has_in_in_in_1().ValueOrDefault())
+      return false;
+    if (has_in_in_in_1().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_in_in_in_1().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_in_in_in_1().ValueOrDefault() &&
+        has_in_in_in_1().ValueOrDefault() &&
+        !in_in_in_1().Equals(emboss_reserved_local_other.in_in_in_1()))
+      return false;
+
+
+
+    if (!has_in_in_in_2().Known()) return false;
+    if (!emboss_reserved_local_other.has_in_in_in_2().Known()) return false;
+
+    if (emboss_reserved_local_other.has_in_in_in_2().ValueOrDefault() &&
+        !has_in_in_in_2().ValueOrDefault())
+      return false;
+    if (has_in_in_in_2().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_in_in_in_2().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_in_in_in_2().ValueOrDefault() &&
+        has_in_in_in_2().ValueOrDefault() &&
+        !in_in_in_2().Equals(emboss_reserved_local_other.in_in_in_2()))
+      return false;
+
+
+
+    if (!has_name_collision().Known()) return false;
+    if (!emboss_reserved_local_other.has_name_collision().Known()) return false;
+
+    if (emboss_reserved_local_other.has_name_collision().ValueOrDefault() &&
+        !has_name_collision().ValueOrDefault())
+      return false;
+    if (has_name_collision().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_name_collision().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_name_collision().ValueOrDefault() &&
+        has_name_collision().ValueOrDefault() &&
+        !name_collision().Equals(emboss_reserved_local_other.name_collision()))
+      return false;
+
+
+
+    if (!has_nested_constant_check().Known()) return false;
+    if (!emboss_reserved_local_other.has_nested_constant_check().Known()) return false;
+
+    if (emboss_reserved_local_other.has_nested_constant_check().ValueOrDefault() &&
+        !has_nested_constant_check().ValueOrDefault())
+      return false;
+    if (has_nested_constant_check().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_nested_constant_check().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_nested_constant_check().ValueOrDefault() &&
+        has_nested_constant_check().ValueOrDefault() &&
+        !nested_constant_check().Equals(emboss_reserved_local_other.nested_constant_check()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericOutView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_in_1().ValueOr(false) &&
+        !has_in_1().ValueOr(false))
+      return false;
+    if (has_in_1().ValueOr(false) &&
+        !emboss_reserved_local_other.has_in_1().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_in_1().ValueOr(false) &&
+        has_in_1().ValueOr(false) &&
+        !in_1().UncheckedEquals(emboss_reserved_local_other.in_1()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_in_2().ValueOr(false) &&
+        !has_in_2().ValueOr(false))
+      return false;
+    if (has_in_2().ValueOr(false) &&
+        !emboss_reserved_local_other.has_in_2().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_in_2().ValueOr(false) &&
+        has_in_2().ValueOr(false) &&
+        !in_2().UncheckedEquals(emboss_reserved_local_other.in_2()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_in_in_1().ValueOr(false) &&
+        !has_in_in_1().ValueOr(false))
+      return false;
+    if (has_in_in_1().ValueOr(false) &&
+        !emboss_reserved_local_other.has_in_in_1().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_in_in_1().ValueOr(false) &&
+        has_in_in_1().ValueOr(false) &&
+        !in_in_1().UncheckedEquals(emboss_reserved_local_other.in_in_1()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_in_in_2().ValueOr(false) &&
+        !has_in_in_2().ValueOr(false))
+      return false;
+    if (has_in_in_2().ValueOr(false) &&
+        !emboss_reserved_local_other.has_in_in_2().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_in_in_2().ValueOr(false) &&
+        has_in_in_2().ValueOr(false) &&
+        !in_in_2().UncheckedEquals(emboss_reserved_local_other.in_in_2()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_in_in_in_1().ValueOr(false) &&
+        !has_in_in_in_1().ValueOr(false))
+      return false;
+    if (has_in_in_in_1().ValueOr(false) &&
+        !emboss_reserved_local_other.has_in_in_in_1().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_in_in_in_1().ValueOr(false) &&
+        has_in_in_in_1().ValueOr(false) &&
+        !in_in_in_1().UncheckedEquals(emboss_reserved_local_other.in_in_in_1()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_in_in_in_2().ValueOr(false) &&
+        !has_in_in_in_2().ValueOr(false))
+      return false;
+    if (has_in_in_in_2().ValueOr(false) &&
+        !emboss_reserved_local_other.has_in_in_in_2().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_in_in_in_2().ValueOr(false) &&
+        has_in_in_in_2().ValueOr(false) &&
+        !in_in_in_2().UncheckedEquals(emboss_reserved_local_other.in_in_in_2()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_name_collision().ValueOr(false) &&
+        !has_name_collision().ValueOr(false))
+      return false;
+    if (has_name_collision().ValueOr(false) &&
+        !emboss_reserved_local_other.has_name_collision().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_name_collision().ValueOr(false) &&
+        has_name_collision().ValueOr(false) &&
+        !name_collision().UncheckedEquals(emboss_reserved_local_other.name_collision()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_nested_constant_check().ValueOr(false) &&
+        !has_nested_constant_check().ValueOr(false))
+      return false;
+    if (has_nested_constant_check().ValueOr(false) &&
+        !emboss_reserved_local_other.has_nested_constant_check().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_nested_constant_check().ValueOr(false) &&
+        has_nested_constant_check().ValueOr(false) &&
+        !nested_constant_check().UncheckedEquals(emboss_reserved_local_other.nested_constant_check()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericOutView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericOutView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericOutView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "in_1") {
+        if (!in_1().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "in_2") {
+        if (!in_2().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "in_in_1") {
+        if (!in_in_1().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "in_in_2") {
+        if (!in_in_2().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "in_in_in_1") {
+        if (!in_in_in_1().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "in_in_in_2") {
+        if (!in_in_in_2().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "name_collision") {
+        if (!name_collision().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "nested_constant_check") {
+        if (!nested_constant_check().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_in_1().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          in_1().IsAggregate() || in_1().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("in_1: ");
+        in_1().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !in_1().IsAggregate() && !in_1().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# in_1: UNREADABLE\n");
+      }
+    }
+
+    if (has_in_2().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          in_2().IsAggregate() || in_2().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("in_2: ");
+        in_2().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !in_2().IsAggregate() && !in_2().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# in_2: UNREADABLE\n");
+      }
+    }
+
+    if (has_in_in_1().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          in_in_1().IsAggregate() || in_in_1().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("in_in_1: ");
+        in_in_1().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !in_in_1().IsAggregate() && !in_in_1().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# in_in_1: UNREADABLE\n");
+      }
+    }
+
+    if (has_in_in_2().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          in_in_2().IsAggregate() || in_in_2().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("in_in_2: ");
+        in_in_2().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !in_in_2().IsAggregate() && !in_in_2().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# in_in_2: UNREADABLE\n");
+      }
+    }
+
+    if (has_in_in_in_1().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          in_in_in_1().IsAggregate() || in_in_in_1().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("in_in_in_1: ");
+        in_in_in_1().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !in_in_in_1().IsAggregate() && !in_in_in_1().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# in_in_in_1: UNREADABLE\n");
+      }
+    }
+
+    if (has_in_in_in_2().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          in_in_in_2().IsAggregate() || in_in_in_2().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("in_in_in_2: ");
+        in_in_in_2().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !in_in_in_2().IsAggregate() && !in_in_in_2().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# in_in_in_2: UNREADABLE\n");
+      }
+    }
+
+    if (has_name_collision().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          name_collision().IsAggregate() || name_collision().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("name_collision: ");
+        name_collision().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !name_collision().IsAggregate() && !name_collision().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# name_collision: UNREADABLE\n");
+      }
+    }
+
+    if (has_nested_constant_check().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          nested_constant_check().IsAggregate() || nested_constant_check().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("nested_constant_check: ");
+        nested_constant_check().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !nested_constant_check().IsAggregate() && !nested_constant_check().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# nested_constant_check: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::test::Out::GenericInView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ in_1() const;
+  ::emboss::support::Maybe<bool> has_in_1() const;
+
+ public:
+  typename ::emboss::test::Out::GenericInView<typename Storage::template OffsetStorageType</**/0, 8>>
+
+ in_2() const;
+  ::emboss::support::Maybe<bool> has_in_2() const;
+
+ public:
+  typename ::emboss::test::Out::In::GenericInInView<typename Storage::template OffsetStorageType</**/0, 16>>
+
+ in_in_1() const;
+  ::emboss::support::Maybe<bool> has_in_in_1() const;
+
+ public:
+  typename ::emboss::test::Out::In::GenericInInView<typename Storage::template OffsetStorageType</**/0, 18>>
+
+ in_in_2() const;
+  ::emboss::support::Maybe<bool> has_in_in_2() const;
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Out::In::InIn::InInIn,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 20>>, 8>>
+
+ in_in_in_1() const;
+  ::emboss::support::Maybe<bool> has_in_in_in_1() const;
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Out::In::InIn::InInIn,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 8>>
+
+ in_in_in_2() const;
+  ::emboss::support::Maybe<bool> has_in_in_in_2() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 22>>, 16>>
+
+ name_collision() const;
+  ::emboss::support::Maybe<bool> has_name_collision() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 24>>, 8>>
+
+ nested_constant_check() const;
+  ::emboss::support::Maybe<bool> has_nested_constant_check() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericOutView;
+};
+using OutView =
+    GenericOutView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using OutWriter =
+    GenericOutView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericOutView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericOutView<
+    GenericOutView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericOutView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeOutView( T &&emboss_reserved_local_arg) {
+  return GenericOutView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericOutView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeOutView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericOutView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericOutView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedOutView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericOutView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace Out {
+namespace In {
+namespace InIn {
+
+}  // namespace InIn
+
+
+namespace InIn {
+inline constexpr ::std::int32_t outer_offset() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(24LL)).ValueOrDefault();
+}
+}  // namespace InIn
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericInInView<Storage>::EmbossReservedVirtualOuterOffsetView::Read() {
+  return InIn::outer_offset();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericInInView<
+    Storage>::EmbossReservedVirtualOuterOffsetView::UncheckedRead() {
+  return InIn::outer_offset();
+}
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Out::In::InIn::InInIn,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericInInView<Storage>::field_enum()
+    const {
+
+  if ( has_field_enum().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Out::In::InIn::InInIn,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Out::In::InIn::InInIn,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericInInView<Storage>::has_field_enum() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::Out::GenericIn2View<typename Storage::template OffsetStorageType</**/0, 1>>
+
+ GenericInInView<Storage>::in_2()
+    const {
+
+  if ( has_in_2().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::Out::GenericIn2View<typename Storage::template OffsetStorageType</**/0, 1>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::Out::GenericIn2View<typename Storage::template OffsetStorageType</**/0, 1>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericInInView<Storage>::has_in_2() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace InIn {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace InIn
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericInInView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return InIn::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericInInView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return InIn::IntrinsicSizeInBytes();
+}
+
+namespace InIn {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace InIn
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericInInView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return InIn::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericInInView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return InIn::MaxSizeInBytes();
+}
+
+namespace InIn {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace InIn
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericInInView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return InIn::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericInInView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return InIn::MinSizeInBytes();
+}
+
+}  // namespace In
+
+
+template <class Storage>
+inline typename ::emboss::test::Out::In::GenericInInView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericInView<Storage>::in_in_1()
+    const {
+
+  if ( has_in_in_1().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::Out::In::GenericInInView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::Out::In::GenericInInView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericInView<Storage>::has_in_in_1() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::Out::In::GenericInInView<typename Storage::template OffsetStorageType</**/0, 2>>
+
+ GenericInView<Storage>::in_in_2()
+    const {
+
+  if ( has_in_in_2().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::Out::In::GenericInInView<typename Storage::template OffsetStorageType</**/0, 2>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::Out::In::GenericInInView<typename Storage::template OffsetStorageType</**/0, 2>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericInView<Storage>::has_in_in_2() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Out::In::InIn::InInIn,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 8>>
+
+ GenericInView<Storage>::in_in_in_1()
+    const {
+
+  if ( has_in_in_in_1().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Out::In::InIn::InInIn,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   4>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Out::In::InIn::InInIn,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericInView<Storage>::has_in_in_in_1() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::Out::GenericIn2View<typename Storage::template OffsetStorageType</**/0, 5>>
+
+ GenericInView<Storage>::in_2()
+    const {
+
+  if ( has_in_2().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::Out::GenericIn2View<typename Storage::template OffsetStorageType</**/0, 5>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   5>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::Out::GenericIn2View<typename Storage::template OffsetStorageType</**/0, 5>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericInView<Storage>::has_in_2() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 8>>
+
+ GenericInView<Storage>::name_collision()
+    const {
+
+  if ( has_name_collision().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   6>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericInView<Storage>::has_name_collision() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+ GenericInView<Storage>::name_collision_check()
+    const {
+
+  if ( has_name_collision_check().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = name_collision();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_2;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<1,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/1, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericInView<Storage>::has_name_collision_check() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericInView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericInView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericInView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericInView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace In {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(256LL)).ValueOrDefault();
+}
+}  // namespace In
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericInView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return In::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericInView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return In::MaxSizeInBytes();
+}
+
+namespace In {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(7LL)).ValueOrDefault();
+}
+}  // namespace In
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericInView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return In::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericInView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return In::MinSizeInBytes();
+}
+
+namespace In2 {
+
+}  // namespace In2
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericIn2View<Storage>::field_byte()
+    const {
+
+  if ( has_field_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericIn2View<Storage>::has_field_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace In2 {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace In2
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericIn2View<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return In2::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericIn2View<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return In2::IntrinsicSizeInBytes();
+}
+
+namespace In2 {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace In2
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericIn2View<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return In2::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericIn2View<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return In2::MaxSizeInBytes();
+}
+
+namespace In2 {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace In2
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericIn2View<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return In2::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericIn2View<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return In2::MinSizeInBytes();
+}
+
+}  // namespace Out
+
+
+template <class Storage>
+inline typename ::emboss::test::Out::GenericInView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericOutView<Storage>::in_1()
+    const {
+
+  if ( has_in_1().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::Out::GenericInView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::Out::GenericInView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericOutView<Storage>::has_in_1() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::Out::GenericInView<typename Storage::template OffsetStorageType</**/0, 8>>
+
+ GenericOutView<Storage>::in_2()
+    const {
+
+  if ( has_in_2().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::Out::GenericInView<typename Storage::template OffsetStorageType</**/0, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   8>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::Out::GenericInView<typename Storage::template OffsetStorageType</**/0, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericOutView<Storage>::has_in_2() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::Out::In::GenericInInView<typename Storage::template OffsetStorageType</**/0, 16>>
+
+ GenericOutView<Storage>::in_in_1()
+    const {
+
+  if ( has_in_in_1().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(16LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::Out::In::GenericInInView<typename Storage::template OffsetStorageType</**/0, 16>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   16>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::Out::In::GenericInInView<typename Storage::template OffsetStorageType</**/0, 16>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericOutView<Storage>::has_in_in_1() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::Out::In::GenericInInView<typename Storage::template OffsetStorageType</**/0, 18>>
+
+ GenericOutView<Storage>::in_in_2()
+    const {
+
+  if ( has_in_in_2().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(18LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::Out::In::GenericInInView<typename Storage::template OffsetStorageType</**/0, 18>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   18>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::Out::In::GenericInInView<typename Storage::template OffsetStorageType</**/0, 18>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericOutView<Storage>::has_in_in_2() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Out::In::InIn::InInIn,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 20>>, 8>>
+
+ GenericOutView<Storage>::in_in_in_1()
+    const {
+
+  if ( has_in_in_in_1().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(20LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Out::In::InIn::InInIn,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 20>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   20>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Out::In::InIn::InInIn,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 20>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericOutView<Storage>::has_in_in_in_1() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Out::In::InIn::InInIn,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 8>>
+
+ GenericOutView<Storage>::in_in_in_2()
+    const {
+
+  if ( has_in_in_in_2().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(21LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Out::In::InIn::InInIn,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   21>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Out::In::InIn::InInIn,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericOutView<Storage>::has_in_in_in_2() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 22>>, 16>>
+
+ GenericOutView<Storage>::name_collision()
+    const {
+
+  if ( has_name_collision().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(22LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 22>>, 16>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   22>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 22>>, 16>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericOutView<Storage>::has_name_collision() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 24>>, 8>>
+
+ GenericOutView<Storage>::nested_constant_check()
+    const {
+
+  if ( has_nested_constant_check().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(24LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 24>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   24>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 24>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericOutView<Storage>::has_nested_constant_check() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Out {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(25LL)).ValueOrDefault();
+}
+}  // namespace Out
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOutView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Out::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOutView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Out::IntrinsicSizeInBytes();
+}
+
+namespace Out {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(25LL)).ValueOrDefault();
+}
+}  // namespace Out
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOutView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Out::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOutView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Out::MaxSizeInBytes();
+}
+
+namespace Out {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(25LL)).ValueOrDefault();
+}
+}  // namespace Out
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOutView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Out::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericOutView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Out::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_SUBTYPES_EMB_H_
+
diff --git a/testdata/golden_cpp/text_format.emb.h b/testdata/golden_cpp/text_format.emb.h
new file mode 100644
index 0000000..46f257d
--- /dev/null
+++ b/testdata/golden_cpp/text_format.emb.h
@@ -0,0 +1,2165 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_TEXT_FORMAT_EMB_H_
+#define TESTDATA_TEXT_FORMAT_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace Vanilla {
+
+}  // namespace Vanilla
+
+
+template <class Storage>
+class GenericVanillaView;
+
+namespace StructWithSkippedFields {
+
+}  // namespace StructWithSkippedFields
+
+
+template <class Storage>
+class GenericStructWithSkippedFieldsView;
+
+namespace StructWithSkippedStructureFields {
+
+}  // namespace StructWithSkippedStructureFields
+
+
+template <class Storage>
+class GenericStructWithSkippedStructureFieldsView;
+
+
+
+
+
+
+namespace Vanilla {
+
+}  // namespace Vanilla
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericVanillaView;
+
+template <class Storage>
+class GenericVanillaView final {
+ public:
+  GenericVanillaView() : backing_() {}
+  explicit GenericVanillaView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericVanillaView(
+      const GenericVanillaView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericVanillaView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericVanillaView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericVanillaView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericVanillaView<Storage> &operator=(
+      const GenericVanillaView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_a().Known()) return false;
+    if (has_a().ValueOrDefault() && !a().Ok()) return false;
+
+
+    if (!has_b().Known()) return false;
+    if (has_b().ValueOrDefault() && !b().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericVanillaView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_a().Known()) return false;
+    if (!emboss_reserved_local_other.has_a().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        !has_a().ValueOrDefault())
+      return false;
+    if (has_a().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        has_a().ValueOrDefault() &&
+        !a().Equals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (!has_b().Known()) return false;
+    if (!emboss_reserved_local_other.has_b().Known()) return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        !has_b().ValueOrDefault())
+      return false;
+    if (has_b().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_b().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        has_b().ValueOrDefault() &&
+        !b().Equals(emboss_reserved_local_other.b()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericVanillaView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        !has_a().ValueOr(false))
+      return false;
+    if (has_a().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        has_a().ValueOr(false) &&
+        !a().UncheckedEquals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        !has_b().ValueOr(false))
+      return false;
+    if (has_b().ValueOr(false) &&
+        !emboss_reserved_local_other.has_b().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        has_b().ValueOr(false) &&
+        !b().UncheckedEquals(emboss_reserved_local_other.b()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericVanillaView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericVanillaView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericVanillaView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "a") {
+        if (!a().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "b") {
+        if (!b().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_a().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a().IsAggregate() || a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a: ");
+        a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a().IsAggregate() && !a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a: UNREADABLE\n");
+      }
+    }
+
+    if (has_b().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b().IsAggregate() || b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("b: ");
+        b().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !b().IsAggregate() && !b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::NullByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ a() const;
+  ::emboss::support::Maybe<bool> has_a() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::NullByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ b() const;
+  ::emboss::support::Maybe<bool> has_b() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericVanillaView;
+};
+using VanillaView =
+    GenericVanillaView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using VanillaWriter =
+    GenericVanillaView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericVanillaView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericVanillaView<
+    GenericVanillaView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericVanillaView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeVanillaView( T &&emboss_reserved_local_arg) {
+  return GenericVanillaView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericVanillaView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeVanillaView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericVanillaView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericVanillaView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedVanillaView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericVanillaView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace StructWithSkippedFields {
+
+}  // namespace StructWithSkippedFields
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructWithSkippedFieldsView;
+
+template <class Storage>
+class GenericStructWithSkippedFieldsView final {
+ public:
+  GenericStructWithSkippedFieldsView() : backing_() {}
+  explicit GenericStructWithSkippedFieldsView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructWithSkippedFieldsView(
+      const GenericStructWithSkippedFieldsView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericStructWithSkippedFieldsView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericStructWithSkippedFieldsView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericStructWithSkippedFieldsView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructWithSkippedFieldsView<Storage> &operator=(
+      const GenericStructWithSkippedFieldsView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_a().Known()) return false;
+    if (has_a().ValueOrDefault() && !a().Ok()) return false;
+
+
+    if (!has_b().Known()) return false;
+    if (has_b().ValueOrDefault() && !b().Ok()) return false;
+
+
+    if (!has_c().Known()) return false;
+    if (has_c().ValueOrDefault() && !c().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericStructWithSkippedFieldsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_a().Known()) return false;
+    if (!emboss_reserved_local_other.has_a().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        !has_a().ValueOrDefault())
+      return false;
+    if (has_a().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        has_a().ValueOrDefault() &&
+        !a().Equals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (!has_b().Known()) return false;
+    if (!emboss_reserved_local_other.has_b().Known()) return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        !has_b().ValueOrDefault())
+      return false;
+    if (has_b().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_b().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        has_b().ValueOrDefault() &&
+        !b().Equals(emboss_reserved_local_other.b()))
+      return false;
+
+
+
+    if (!has_c().Known()) return false;
+    if (!emboss_reserved_local_other.has_c().Known()) return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOrDefault() &&
+        !has_c().ValueOrDefault())
+      return false;
+    if (has_c().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_c().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOrDefault() &&
+        has_c().ValueOrDefault() &&
+        !c().Equals(emboss_reserved_local_other.c()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericStructWithSkippedFieldsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        !has_a().ValueOr(false))
+      return false;
+    if (has_a().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        has_a().ValueOr(false) &&
+        !a().UncheckedEquals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        !has_b().ValueOr(false))
+      return false;
+    if (has_b().ValueOr(false) &&
+        !emboss_reserved_local_other.has_b().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        has_b().ValueOr(false) &&
+        !b().UncheckedEquals(emboss_reserved_local_other.b()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_c().ValueOr(false) &&
+        !has_c().ValueOr(false))
+      return false;
+    if (has_c().ValueOr(false) &&
+        !emboss_reserved_local_other.has_c().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOr(false) &&
+        has_c().ValueOr(false) &&
+        !c().UncheckedEquals(emboss_reserved_local_other.c()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericStructWithSkippedFieldsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericStructWithSkippedFieldsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericStructWithSkippedFieldsView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "a") {
+        if (!a().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "b") {
+        if (!b().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "c") {
+        if (!c().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_a().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a().IsAggregate() || a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a: ");
+        a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a().IsAggregate() && !a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a: UNREADABLE\n");
+      }
+    }
+
+    if (has_c().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          c().IsAggregate() || c().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("c: ");
+        c().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !c().IsAggregate() && !c().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# c: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::NullByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ a() const;
+  ::emboss::support::Maybe<bool> has_a() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::NullByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ b() const;
+  ::emboss::support::Maybe<bool> has_b() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::NullByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ c() const;
+  ::emboss::support::Maybe<bool> has_c() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericStructWithSkippedFieldsView;
+};
+using StructWithSkippedFieldsView =
+    GenericStructWithSkippedFieldsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using StructWithSkippedFieldsWriter =
+    GenericStructWithSkippedFieldsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructWithSkippedFieldsView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericStructWithSkippedFieldsView<
+    GenericStructWithSkippedFieldsView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericStructWithSkippedFieldsView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeStructWithSkippedFieldsView( T &&emboss_reserved_local_arg) {
+  return GenericStructWithSkippedFieldsView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericStructWithSkippedFieldsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeStructWithSkippedFieldsView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericStructWithSkippedFieldsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericStructWithSkippedFieldsView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedStructWithSkippedFieldsView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericStructWithSkippedFieldsView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace StructWithSkippedStructureFields {
+
+}  // namespace StructWithSkippedStructureFields
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructWithSkippedStructureFieldsView;
+
+template <class Storage>
+class GenericStructWithSkippedStructureFieldsView final {
+ public:
+  GenericStructWithSkippedStructureFieldsView() : backing_() {}
+  explicit GenericStructWithSkippedStructureFieldsView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructWithSkippedStructureFieldsView(
+      const GenericStructWithSkippedStructureFieldsView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericStructWithSkippedStructureFieldsView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericStructWithSkippedStructureFieldsView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericStructWithSkippedStructureFieldsView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructWithSkippedStructureFieldsView<Storage> &operator=(
+      const GenericStructWithSkippedStructureFieldsView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_a().Known()) return false;
+    if (has_a().ValueOrDefault() && !a().Ok()) return false;
+
+
+    if (!has_b().Known()) return false;
+    if (has_b().ValueOrDefault() && !b().Ok()) return false;
+
+
+    if (!has_c().Known()) return false;
+    if (has_c().ValueOrDefault() && !c().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericStructWithSkippedStructureFieldsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_a().Known()) return false;
+    if (!emboss_reserved_local_other.has_a().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        !has_a().ValueOrDefault())
+      return false;
+    if (has_a().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        has_a().ValueOrDefault() &&
+        !a().Equals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (!has_b().Known()) return false;
+    if (!emboss_reserved_local_other.has_b().Known()) return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        !has_b().ValueOrDefault())
+      return false;
+    if (has_b().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_b().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        has_b().ValueOrDefault() &&
+        !b().Equals(emboss_reserved_local_other.b()))
+      return false;
+
+
+
+    if (!has_c().Known()) return false;
+    if (!emboss_reserved_local_other.has_c().Known()) return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOrDefault() &&
+        !has_c().ValueOrDefault())
+      return false;
+    if (has_c().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_c().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOrDefault() &&
+        has_c().ValueOrDefault() &&
+        !c().Equals(emboss_reserved_local_other.c()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericStructWithSkippedStructureFieldsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        !has_a().ValueOr(false))
+      return false;
+    if (has_a().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        has_a().ValueOr(false) &&
+        !a().UncheckedEquals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        !has_b().ValueOr(false))
+      return false;
+    if (has_b().ValueOr(false) &&
+        !emboss_reserved_local_other.has_b().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        has_b().ValueOr(false) &&
+        !b().UncheckedEquals(emboss_reserved_local_other.b()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_c().ValueOr(false) &&
+        !has_c().ValueOr(false))
+      return false;
+    if (has_c().ValueOr(false) &&
+        !emboss_reserved_local_other.has_c().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_c().ValueOr(false) &&
+        has_c().ValueOr(false) &&
+        !c().UncheckedEquals(emboss_reserved_local_other.c()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericStructWithSkippedStructureFieldsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericStructWithSkippedStructureFieldsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericStructWithSkippedStructureFieldsView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "a") {
+        if (!a().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "b") {
+        if (!b().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "c") {
+        if (!c().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_a().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a().IsAggregate() || a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a: ");
+        a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a().IsAggregate() && !a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a: UNREADABLE\n");
+      }
+    }
+
+    if (has_c().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          c().IsAggregate() || c().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("c: ");
+        c().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !c().IsAggregate() && !c().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# c: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::test::GenericVanillaView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ a() const;
+  ::emboss::support::Maybe<bool> has_a() const;
+
+ public:
+  typename ::emboss::test::GenericVanillaView<typename Storage::template OffsetStorageType</**/0, 2>>
+
+ b() const;
+  ::emboss::support::Maybe<bool> has_b() const;
+
+ public:
+  typename ::emboss::test::GenericVanillaView<typename Storage::template OffsetStorageType</**/0, 4>>
+
+ c() const;
+  ::emboss::support::Maybe<bool> has_c() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericStructWithSkippedStructureFieldsView;
+};
+using StructWithSkippedStructureFieldsView =
+    GenericStructWithSkippedStructureFieldsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using StructWithSkippedStructureFieldsWriter =
+    GenericStructWithSkippedStructureFieldsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructWithSkippedStructureFieldsView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericStructWithSkippedStructureFieldsView<
+    GenericStructWithSkippedStructureFieldsView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericStructWithSkippedStructureFieldsView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeStructWithSkippedStructureFieldsView( T &&emboss_reserved_local_arg) {
+  return GenericStructWithSkippedStructureFieldsView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericStructWithSkippedStructureFieldsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeStructWithSkippedStructureFieldsView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericStructWithSkippedStructureFieldsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericStructWithSkippedStructureFieldsView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedStructWithSkippedStructureFieldsView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericStructWithSkippedStructureFieldsView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace Vanilla {
+
+}  // namespace Vanilla
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::NullByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericVanillaView<Storage>::a()
+    const {
+
+  if ( has_a().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::NullByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::NullByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericVanillaView<Storage>::has_a() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::NullByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericVanillaView<Storage>::b()
+    const {
+
+  if ( has_b().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::NullByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::NullByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericVanillaView<Storage>::has_b() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Vanilla {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace Vanilla
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericVanillaView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Vanilla::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericVanillaView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Vanilla::IntrinsicSizeInBytes();
+}
+
+namespace Vanilla {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace Vanilla
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericVanillaView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Vanilla::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericVanillaView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Vanilla::MaxSizeInBytes();
+}
+
+namespace Vanilla {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace Vanilla
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericVanillaView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Vanilla::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericVanillaView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Vanilla::MinSizeInBytes();
+}
+namespace StructWithSkippedFields {
+
+}  // namespace StructWithSkippedFields
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::NullByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericStructWithSkippedFieldsView<Storage>::a()
+    const {
+
+  if ( has_a().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::NullByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::NullByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructWithSkippedFieldsView<Storage>::has_a() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::NullByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericStructWithSkippedFieldsView<Storage>::b()
+    const {
+
+  if ( has_b().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::NullByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::NullByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructWithSkippedFieldsView<Storage>::has_b() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::NullByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+ GenericStructWithSkippedFieldsView<Storage>::c()
+    const {
+
+  if ( has_c().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::NullByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::NullByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructWithSkippedFieldsView<Storage>::has_c() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace StructWithSkippedFields {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace StructWithSkippedFields
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructWithSkippedFieldsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return StructWithSkippedFields::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructWithSkippedFieldsView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return StructWithSkippedFields::IntrinsicSizeInBytes();
+}
+
+namespace StructWithSkippedFields {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace StructWithSkippedFields
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructWithSkippedFieldsView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return StructWithSkippedFields::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructWithSkippedFieldsView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return StructWithSkippedFields::MaxSizeInBytes();
+}
+
+namespace StructWithSkippedFields {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace StructWithSkippedFields
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructWithSkippedFieldsView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return StructWithSkippedFields::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructWithSkippedFieldsView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return StructWithSkippedFields::MinSizeInBytes();
+}
+namespace StructWithSkippedStructureFields {
+
+}  // namespace StructWithSkippedStructureFields
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericVanillaView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericStructWithSkippedStructureFieldsView<Storage>::a()
+    const {
+
+  if ( has_a().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericVanillaView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericVanillaView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructWithSkippedStructureFieldsView<Storage>::has_a() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericVanillaView<typename Storage::template OffsetStorageType</**/0, 2>>
+
+ GenericStructWithSkippedStructureFieldsView<Storage>::b()
+    const {
+
+  if ( has_b().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericVanillaView<typename Storage::template OffsetStorageType</**/0, 2>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericVanillaView<typename Storage::template OffsetStorageType</**/0, 2>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructWithSkippedStructureFieldsView<Storage>::has_b() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericVanillaView<typename Storage::template OffsetStorageType</**/0, 4>>
+
+ GenericStructWithSkippedStructureFieldsView<Storage>::c()
+    const {
+
+  if ( has_c().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericVanillaView<typename Storage::template OffsetStorageType</**/0, 4>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   4>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericVanillaView<typename Storage::template OffsetStorageType</**/0, 4>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructWithSkippedStructureFieldsView<Storage>::has_c() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace StructWithSkippedStructureFields {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL)).ValueOrDefault();
+}
+}  // namespace StructWithSkippedStructureFields
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructWithSkippedStructureFieldsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return StructWithSkippedStructureFields::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructWithSkippedStructureFieldsView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return StructWithSkippedStructureFields::IntrinsicSizeInBytes();
+}
+
+namespace StructWithSkippedStructureFields {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL)).ValueOrDefault();
+}
+}  // namespace StructWithSkippedStructureFields
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructWithSkippedStructureFieldsView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return StructWithSkippedStructureFields::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructWithSkippedStructureFieldsView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return StructWithSkippedStructureFields::MaxSizeInBytes();
+}
+
+namespace StructWithSkippedStructureFields {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL)).ValueOrDefault();
+}
+}  // namespace StructWithSkippedStructureFields
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructWithSkippedStructureFieldsView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return StructWithSkippedStructureFields::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructWithSkippedStructureFieldsView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return StructWithSkippedStructureFields::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_TEXT_FORMAT_EMB_H_
+
diff --git a/testdata/golden_cpp/uint_sizes.emb.h b/testdata/golden_cpp/uint_sizes.emb.h
new file mode 100644
index 0000000..df5eb3f
--- /dev/null
+++ b/testdata/golden_cpp/uint_sizes.emb.h
@@ -0,0 +1,8942 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_UINT_SIZES_EMB_H_
+#define TESTDATA_UINT_SIZES_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace Sizes {
+
+}  // namespace Sizes
+
+
+template <class Storage>
+class GenericSizesView;
+
+namespace BigEndianSizes {
+
+}  // namespace BigEndianSizes
+
+
+template <class Storage>
+class GenericBigEndianSizesView;
+
+namespace AlternatingEndianSizes {
+
+}  // namespace AlternatingEndianSizes
+
+
+template <class Storage>
+class GenericAlternatingEndianSizesView;
+
+namespace EnumSizes {
+
+}  // namespace EnumSizes
+
+
+template <class Storage>
+class GenericEnumSizesView;
+
+namespace ExplicitlySizedEnumSizes {
+namespace EmbossReservedAnonymousField1 {
+
+}  // namespace EmbossReservedAnonymousField1
+
+
+template <class Storage>
+class GenericEmbossReservedAnonymousField1View;
+
+
+}  // namespace ExplicitlySizedEnumSizes
+
+
+template <class Storage>
+class GenericExplicitlySizedEnumSizesView;
+
+enum class Enum : ::std::uint64_t;
+
+enum class ExplicitlySizedEnum : ::std::uint32_t;
+
+namespace ArraySizes {
+
+}  // namespace ArraySizes
+
+
+template <class Storage>
+class GenericArraySizesView;
+
+
+
+
+
+
+
+
+
+
+
+
+namespace Sizes {
+
+}  // namespace Sizes
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericSizesView;
+
+template <class Storage>
+class GenericSizesView final {
+ public:
+  GenericSizesView() : backing_() {}
+  explicit GenericSizesView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericSizesView(
+      const GenericSizesView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericSizesView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericSizesView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericSizesView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericSizesView<Storage> &operator=(
+      const GenericSizesView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_one_byte().Known()) return false;
+    if (has_one_byte().ValueOrDefault() && !one_byte().Ok()) return false;
+
+
+    if (!has_two_byte().Known()) return false;
+    if (has_two_byte().ValueOrDefault() && !two_byte().Ok()) return false;
+
+
+    if (!has_three_byte().Known()) return false;
+    if (has_three_byte().ValueOrDefault() && !three_byte().Ok()) return false;
+
+
+    if (!has_four_byte().Known()) return false;
+    if (has_four_byte().ValueOrDefault() && !four_byte().Ok()) return false;
+
+
+    if (!has_five_byte().Known()) return false;
+    if (has_five_byte().ValueOrDefault() && !five_byte().Ok()) return false;
+
+
+    if (!has_six_byte().Known()) return false;
+    if (has_six_byte().ValueOrDefault() && !six_byte().Ok()) return false;
+
+
+    if (!has_seven_byte().Known()) return false;
+    if (has_seven_byte().ValueOrDefault() && !seven_byte().Ok()) return false;
+
+
+    if (!has_eight_byte().Known()) return false;
+    if (has_eight_byte().ValueOrDefault() && !eight_byte().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericSizesView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_one_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_one_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOrDefault() &&
+        !has_one_byte().ValueOrDefault())
+      return false;
+    if (has_one_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_one_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOrDefault() &&
+        has_one_byte().ValueOrDefault() &&
+        !one_byte().Equals(emboss_reserved_local_other.one_byte()))
+      return false;
+
+
+
+    if (!has_two_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_two_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOrDefault() &&
+        !has_two_byte().ValueOrDefault())
+      return false;
+    if (has_two_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_two_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOrDefault() &&
+        has_two_byte().ValueOrDefault() &&
+        !two_byte().Equals(emboss_reserved_local_other.two_byte()))
+      return false;
+
+
+
+    if (!has_three_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_three_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOrDefault() &&
+        !has_three_byte().ValueOrDefault())
+      return false;
+    if (has_three_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_three_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOrDefault() &&
+        has_three_byte().ValueOrDefault() &&
+        !three_byte().Equals(emboss_reserved_local_other.three_byte()))
+      return false;
+
+
+
+    if (!has_four_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_four_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOrDefault() &&
+        !has_four_byte().ValueOrDefault())
+      return false;
+    if (has_four_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_four_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOrDefault() &&
+        has_four_byte().ValueOrDefault() &&
+        !four_byte().Equals(emboss_reserved_local_other.four_byte()))
+      return false;
+
+
+
+    if (!has_five_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_five_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOrDefault() &&
+        !has_five_byte().ValueOrDefault())
+      return false;
+    if (has_five_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_five_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOrDefault() &&
+        has_five_byte().ValueOrDefault() &&
+        !five_byte().Equals(emboss_reserved_local_other.five_byte()))
+      return false;
+
+
+
+    if (!has_six_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_six_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOrDefault() &&
+        !has_six_byte().ValueOrDefault())
+      return false;
+    if (has_six_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_six_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOrDefault() &&
+        has_six_byte().ValueOrDefault() &&
+        !six_byte().Equals(emboss_reserved_local_other.six_byte()))
+      return false;
+
+
+
+    if (!has_seven_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_seven_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOrDefault() &&
+        !has_seven_byte().ValueOrDefault())
+      return false;
+    if (has_seven_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_seven_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOrDefault() &&
+        has_seven_byte().ValueOrDefault() &&
+        !seven_byte().Equals(emboss_reserved_local_other.seven_byte()))
+      return false;
+
+
+
+    if (!has_eight_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_eight_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOrDefault() &&
+        !has_eight_byte().ValueOrDefault())
+      return false;
+    if (has_eight_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_eight_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOrDefault() &&
+        has_eight_byte().ValueOrDefault() &&
+        !eight_byte().Equals(emboss_reserved_local_other.eight_byte()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericSizesView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_one_byte().ValueOr(false) &&
+        !has_one_byte().ValueOr(false))
+      return false;
+    if (has_one_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_one_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOr(false) &&
+        has_one_byte().ValueOr(false) &&
+        !one_byte().UncheckedEquals(emboss_reserved_local_other.one_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOr(false) &&
+        !has_two_byte().ValueOr(false))
+      return false;
+    if (has_two_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_two_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOr(false) &&
+        has_two_byte().ValueOr(false) &&
+        !two_byte().UncheckedEquals(emboss_reserved_local_other.two_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOr(false) &&
+        !has_three_byte().ValueOr(false))
+      return false;
+    if (has_three_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_three_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOr(false) &&
+        has_three_byte().ValueOr(false) &&
+        !three_byte().UncheckedEquals(emboss_reserved_local_other.three_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOr(false) &&
+        !has_four_byte().ValueOr(false))
+      return false;
+    if (has_four_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_four_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOr(false) &&
+        has_four_byte().ValueOr(false) &&
+        !four_byte().UncheckedEquals(emboss_reserved_local_other.four_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOr(false) &&
+        !has_five_byte().ValueOr(false))
+      return false;
+    if (has_five_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_five_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOr(false) &&
+        has_five_byte().ValueOr(false) &&
+        !five_byte().UncheckedEquals(emboss_reserved_local_other.five_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOr(false) &&
+        !has_six_byte().ValueOr(false))
+      return false;
+    if (has_six_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_six_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOr(false) &&
+        has_six_byte().ValueOr(false) &&
+        !six_byte().UncheckedEquals(emboss_reserved_local_other.six_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOr(false) &&
+        !has_seven_byte().ValueOr(false))
+      return false;
+    if (has_seven_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_seven_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOr(false) &&
+        has_seven_byte().ValueOr(false) &&
+        !seven_byte().UncheckedEquals(emboss_reserved_local_other.seven_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOr(false) &&
+        !has_eight_byte().ValueOr(false))
+      return false;
+    if (has_eight_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_eight_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOr(false) &&
+        has_eight_byte().ValueOr(false) &&
+        !eight_byte().UncheckedEquals(emboss_reserved_local_other.eight_byte()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericSizesView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericSizesView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericSizesView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "one_byte") {
+        if (!one_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "two_byte") {
+        if (!two_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "three_byte") {
+        if (!three_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "four_byte") {
+        if (!four_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "five_byte") {
+        if (!five_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "six_byte") {
+        if (!six_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "seven_byte") {
+        if (!seven_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "eight_byte") {
+        if (!eight_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_one_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          one_byte().IsAggregate() || one_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("one_byte: ");
+        one_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !one_byte().IsAggregate() && !one_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# one_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_two_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          two_byte().IsAggregate() || two_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("two_byte: ");
+        two_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !two_byte().IsAggregate() && !two_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# two_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_three_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          three_byte().IsAggregate() || three_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("three_byte: ");
+        three_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !three_byte().IsAggregate() && !three_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# three_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_four_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          four_byte().IsAggregate() || four_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("four_byte: ");
+        four_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !four_byte().IsAggregate() && !four_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# four_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_five_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          five_byte().IsAggregate() || five_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("five_byte: ");
+        five_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !five_byte().IsAggregate() && !five_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# five_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_six_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          six_byte().IsAggregate() || six_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("six_byte: ");
+        six_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !six_byte().IsAggregate() && !six_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# six_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_seven_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          seven_byte().IsAggregate() || seven_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("seven_byte: ");
+        seven_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !seven_byte().IsAggregate() && !seven_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# seven_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_eight_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          eight_byte().IsAggregate() || eight_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("eight_byte: ");
+        eight_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !eight_byte().IsAggregate() && !eight_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# eight_byte: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ one_byte() const;
+  ::emboss::support::Maybe<bool> has_one_byte() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+ two_byte() const;
+  ::emboss::support::Maybe<bool> has_two_byte() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+ three_byte() const;
+  ::emboss::support::Maybe<bool> has_three_byte() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+ four_byte() const;
+  ::emboss::support::Maybe<bool> has_four_byte() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 40>>
+
+ five_byte() const;
+  ::emboss::support::Maybe<bool> has_five_byte() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 15>>, 48>>
+
+ six_byte() const;
+  ::emboss::support::Maybe<bool> has_six_byte() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 56>>
+
+ seven_byte() const;
+  ::emboss::support::Maybe<bool> has_seven_byte() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 28>>, 64>>
+
+ eight_byte() const;
+  ::emboss::support::Maybe<bool> has_eight_byte() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericSizesView;
+};
+using SizesView =
+    GenericSizesView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using SizesWriter =
+    GenericSizesView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericSizesView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericSizesView<
+    GenericSizesView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericSizesView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeSizesView( T &&emboss_reserved_local_arg) {
+  return GenericSizesView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericSizesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeSizesView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericSizesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericSizesView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedSizesView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericSizesView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+
+
+
+
+
+namespace BigEndianSizes {
+
+}  // namespace BigEndianSizes
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericBigEndianSizesView;
+
+template <class Storage>
+class GenericBigEndianSizesView final {
+ public:
+  GenericBigEndianSizesView() : backing_() {}
+  explicit GenericBigEndianSizesView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericBigEndianSizesView(
+      const GenericBigEndianSizesView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericBigEndianSizesView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericBigEndianSizesView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericBigEndianSizesView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericBigEndianSizesView<Storage> &operator=(
+      const GenericBigEndianSizesView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_one_byte().Known()) return false;
+    if (has_one_byte().ValueOrDefault() && !one_byte().Ok()) return false;
+
+
+    if (!has_two_byte().Known()) return false;
+    if (has_two_byte().ValueOrDefault() && !two_byte().Ok()) return false;
+
+
+    if (!has_three_byte().Known()) return false;
+    if (has_three_byte().ValueOrDefault() && !three_byte().Ok()) return false;
+
+
+    if (!has_four_byte().Known()) return false;
+    if (has_four_byte().ValueOrDefault() && !four_byte().Ok()) return false;
+
+
+    if (!has_five_byte().Known()) return false;
+    if (has_five_byte().ValueOrDefault() && !five_byte().Ok()) return false;
+
+
+    if (!has_six_byte().Known()) return false;
+    if (has_six_byte().ValueOrDefault() && !six_byte().Ok()) return false;
+
+
+    if (!has_seven_byte().Known()) return false;
+    if (has_seven_byte().ValueOrDefault() && !seven_byte().Ok()) return false;
+
+
+    if (!has_eight_byte().Known()) return false;
+    if (has_eight_byte().ValueOrDefault() && !eight_byte().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericBigEndianSizesView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_one_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_one_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOrDefault() &&
+        !has_one_byte().ValueOrDefault())
+      return false;
+    if (has_one_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_one_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOrDefault() &&
+        has_one_byte().ValueOrDefault() &&
+        !one_byte().Equals(emboss_reserved_local_other.one_byte()))
+      return false;
+
+
+
+    if (!has_two_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_two_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOrDefault() &&
+        !has_two_byte().ValueOrDefault())
+      return false;
+    if (has_two_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_two_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOrDefault() &&
+        has_two_byte().ValueOrDefault() &&
+        !two_byte().Equals(emboss_reserved_local_other.two_byte()))
+      return false;
+
+
+
+    if (!has_three_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_three_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOrDefault() &&
+        !has_three_byte().ValueOrDefault())
+      return false;
+    if (has_three_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_three_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOrDefault() &&
+        has_three_byte().ValueOrDefault() &&
+        !three_byte().Equals(emboss_reserved_local_other.three_byte()))
+      return false;
+
+
+
+    if (!has_four_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_four_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOrDefault() &&
+        !has_four_byte().ValueOrDefault())
+      return false;
+    if (has_four_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_four_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOrDefault() &&
+        has_four_byte().ValueOrDefault() &&
+        !four_byte().Equals(emboss_reserved_local_other.four_byte()))
+      return false;
+
+
+
+    if (!has_five_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_five_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOrDefault() &&
+        !has_five_byte().ValueOrDefault())
+      return false;
+    if (has_five_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_five_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOrDefault() &&
+        has_five_byte().ValueOrDefault() &&
+        !five_byte().Equals(emboss_reserved_local_other.five_byte()))
+      return false;
+
+
+
+    if (!has_six_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_six_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOrDefault() &&
+        !has_six_byte().ValueOrDefault())
+      return false;
+    if (has_six_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_six_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOrDefault() &&
+        has_six_byte().ValueOrDefault() &&
+        !six_byte().Equals(emboss_reserved_local_other.six_byte()))
+      return false;
+
+
+
+    if (!has_seven_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_seven_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOrDefault() &&
+        !has_seven_byte().ValueOrDefault())
+      return false;
+    if (has_seven_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_seven_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOrDefault() &&
+        has_seven_byte().ValueOrDefault() &&
+        !seven_byte().Equals(emboss_reserved_local_other.seven_byte()))
+      return false;
+
+
+
+    if (!has_eight_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_eight_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOrDefault() &&
+        !has_eight_byte().ValueOrDefault())
+      return false;
+    if (has_eight_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_eight_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOrDefault() &&
+        has_eight_byte().ValueOrDefault() &&
+        !eight_byte().Equals(emboss_reserved_local_other.eight_byte()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericBigEndianSizesView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_one_byte().ValueOr(false) &&
+        !has_one_byte().ValueOr(false))
+      return false;
+    if (has_one_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_one_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOr(false) &&
+        has_one_byte().ValueOr(false) &&
+        !one_byte().UncheckedEquals(emboss_reserved_local_other.one_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOr(false) &&
+        !has_two_byte().ValueOr(false))
+      return false;
+    if (has_two_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_two_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOr(false) &&
+        has_two_byte().ValueOr(false) &&
+        !two_byte().UncheckedEquals(emboss_reserved_local_other.two_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOr(false) &&
+        !has_three_byte().ValueOr(false))
+      return false;
+    if (has_three_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_three_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOr(false) &&
+        has_three_byte().ValueOr(false) &&
+        !three_byte().UncheckedEquals(emboss_reserved_local_other.three_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOr(false) &&
+        !has_four_byte().ValueOr(false))
+      return false;
+    if (has_four_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_four_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOr(false) &&
+        has_four_byte().ValueOr(false) &&
+        !four_byte().UncheckedEquals(emboss_reserved_local_other.four_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOr(false) &&
+        !has_five_byte().ValueOr(false))
+      return false;
+    if (has_five_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_five_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOr(false) &&
+        has_five_byte().ValueOr(false) &&
+        !five_byte().UncheckedEquals(emboss_reserved_local_other.five_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOr(false) &&
+        !has_six_byte().ValueOr(false))
+      return false;
+    if (has_six_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_six_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOr(false) &&
+        has_six_byte().ValueOr(false) &&
+        !six_byte().UncheckedEquals(emboss_reserved_local_other.six_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOr(false) &&
+        !has_seven_byte().ValueOr(false))
+      return false;
+    if (has_seven_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_seven_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOr(false) &&
+        has_seven_byte().ValueOr(false) &&
+        !seven_byte().UncheckedEquals(emboss_reserved_local_other.seven_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOr(false) &&
+        !has_eight_byte().ValueOr(false))
+      return false;
+    if (has_eight_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_eight_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOr(false) &&
+        has_eight_byte().ValueOr(false) &&
+        !eight_byte().UncheckedEquals(emboss_reserved_local_other.eight_byte()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericBigEndianSizesView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericBigEndianSizesView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericBigEndianSizesView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "one_byte") {
+        if (!one_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "two_byte") {
+        if (!two_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "three_byte") {
+        if (!three_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "four_byte") {
+        if (!four_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "five_byte") {
+        if (!five_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "six_byte") {
+        if (!six_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "seven_byte") {
+        if (!seven_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "eight_byte") {
+        if (!eight_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_one_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          one_byte().IsAggregate() || one_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("one_byte: ");
+        one_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !one_byte().IsAggregate() && !one_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# one_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_two_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          two_byte().IsAggregate() || two_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("two_byte: ");
+        two_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !two_byte().IsAggregate() && !two_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# two_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_three_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          three_byte().IsAggregate() || three_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("three_byte: ");
+        three_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !three_byte().IsAggregate() && !three_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# three_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_four_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          four_byte().IsAggregate() || four_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("four_byte: ");
+        four_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !four_byte().IsAggregate() && !four_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# four_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_five_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          five_byte().IsAggregate() || five_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("five_byte: ");
+        five_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !five_byte().IsAggregate() && !five_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# five_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_six_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          six_byte().IsAggregate() || six_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("six_byte: ");
+        six_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !six_byte().IsAggregate() && !six_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# six_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_seven_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          seven_byte().IsAggregate() || seven_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("seven_byte: ");
+        seven_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !seven_byte().IsAggregate() && !seven_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# seven_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_eight_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          eight_byte().IsAggregate() || eight_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("eight_byte: ");
+        eight_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !eight_byte().IsAggregate() && !eight_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# eight_byte: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ one_byte() const;
+  ::emboss::support::Maybe<bool> has_one_byte() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+ two_byte() const;
+  ::emboss::support::Maybe<bool> has_two_byte() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+ three_byte() const;
+  ::emboss::support::Maybe<bool> has_three_byte() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+ four_byte() const;
+  ::emboss::support::Maybe<bool> has_four_byte() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 40>>
+
+ five_byte() const;
+  ::emboss::support::Maybe<bool> has_five_byte() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 15>>, 48>>
+
+ six_byte() const;
+  ::emboss::support::Maybe<bool> has_six_byte() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 56>>
+
+ seven_byte() const;
+  ::emboss::support::Maybe<bool> has_seven_byte() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 28>>, 64>>
+
+ eight_byte() const;
+  ::emboss::support::Maybe<bool> has_eight_byte() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericBigEndianSizesView;
+};
+using BigEndianSizesView =
+    GenericBigEndianSizesView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using BigEndianSizesWriter =
+    GenericBigEndianSizesView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericBigEndianSizesView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericBigEndianSizesView<
+    GenericBigEndianSizesView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericBigEndianSizesView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeBigEndianSizesView( T &&emboss_reserved_local_arg) {
+  return GenericBigEndianSizesView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericBigEndianSizesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeBigEndianSizesView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericBigEndianSizesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericBigEndianSizesView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedBigEndianSizesView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericBigEndianSizesView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+
+
+
+
+
+namespace AlternatingEndianSizes {
+
+}  // namespace AlternatingEndianSizes
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericAlternatingEndianSizesView;
+
+template <class Storage>
+class GenericAlternatingEndianSizesView final {
+ public:
+  GenericAlternatingEndianSizesView() : backing_() {}
+  explicit GenericAlternatingEndianSizesView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericAlternatingEndianSizesView(
+      const GenericAlternatingEndianSizesView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericAlternatingEndianSizesView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericAlternatingEndianSizesView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericAlternatingEndianSizesView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericAlternatingEndianSizesView<Storage> &operator=(
+      const GenericAlternatingEndianSizesView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_one_byte().Known()) return false;
+    if (has_one_byte().ValueOrDefault() && !one_byte().Ok()) return false;
+
+
+    if (!has_two_byte().Known()) return false;
+    if (has_two_byte().ValueOrDefault() && !two_byte().Ok()) return false;
+
+
+    if (!has_three_byte().Known()) return false;
+    if (has_three_byte().ValueOrDefault() && !three_byte().Ok()) return false;
+
+
+    if (!has_four_byte().Known()) return false;
+    if (has_four_byte().ValueOrDefault() && !four_byte().Ok()) return false;
+
+
+    if (!has_five_byte().Known()) return false;
+    if (has_five_byte().ValueOrDefault() && !five_byte().Ok()) return false;
+
+
+    if (!has_six_byte().Known()) return false;
+    if (has_six_byte().ValueOrDefault() && !six_byte().Ok()) return false;
+
+
+    if (!has_seven_byte().Known()) return false;
+    if (has_seven_byte().ValueOrDefault() && !seven_byte().Ok()) return false;
+
+
+    if (!has_eight_byte().Known()) return false;
+    if (has_eight_byte().ValueOrDefault() && !eight_byte().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericAlternatingEndianSizesView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_one_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_one_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOrDefault() &&
+        !has_one_byte().ValueOrDefault())
+      return false;
+    if (has_one_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_one_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOrDefault() &&
+        has_one_byte().ValueOrDefault() &&
+        !one_byte().Equals(emboss_reserved_local_other.one_byte()))
+      return false;
+
+
+
+    if (!has_two_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_two_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOrDefault() &&
+        !has_two_byte().ValueOrDefault())
+      return false;
+    if (has_two_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_two_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOrDefault() &&
+        has_two_byte().ValueOrDefault() &&
+        !two_byte().Equals(emboss_reserved_local_other.two_byte()))
+      return false;
+
+
+
+    if (!has_three_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_three_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOrDefault() &&
+        !has_three_byte().ValueOrDefault())
+      return false;
+    if (has_three_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_three_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOrDefault() &&
+        has_three_byte().ValueOrDefault() &&
+        !three_byte().Equals(emboss_reserved_local_other.three_byte()))
+      return false;
+
+
+
+    if (!has_four_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_four_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOrDefault() &&
+        !has_four_byte().ValueOrDefault())
+      return false;
+    if (has_four_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_four_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOrDefault() &&
+        has_four_byte().ValueOrDefault() &&
+        !four_byte().Equals(emboss_reserved_local_other.four_byte()))
+      return false;
+
+
+
+    if (!has_five_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_five_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOrDefault() &&
+        !has_five_byte().ValueOrDefault())
+      return false;
+    if (has_five_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_five_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOrDefault() &&
+        has_five_byte().ValueOrDefault() &&
+        !five_byte().Equals(emboss_reserved_local_other.five_byte()))
+      return false;
+
+
+
+    if (!has_six_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_six_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOrDefault() &&
+        !has_six_byte().ValueOrDefault())
+      return false;
+    if (has_six_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_six_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOrDefault() &&
+        has_six_byte().ValueOrDefault() &&
+        !six_byte().Equals(emboss_reserved_local_other.six_byte()))
+      return false;
+
+
+
+    if (!has_seven_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_seven_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOrDefault() &&
+        !has_seven_byte().ValueOrDefault())
+      return false;
+    if (has_seven_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_seven_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOrDefault() &&
+        has_seven_byte().ValueOrDefault() &&
+        !seven_byte().Equals(emboss_reserved_local_other.seven_byte()))
+      return false;
+
+
+
+    if (!has_eight_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_eight_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOrDefault() &&
+        !has_eight_byte().ValueOrDefault())
+      return false;
+    if (has_eight_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_eight_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOrDefault() &&
+        has_eight_byte().ValueOrDefault() &&
+        !eight_byte().Equals(emboss_reserved_local_other.eight_byte()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericAlternatingEndianSizesView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_one_byte().ValueOr(false) &&
+        !has_one_byte().ValueOr(false))
+      return false;
+    if (has_one_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_one_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOr(false) &&
+        has_one_byte().ValueOr(false) &&
+        !one_byte().UncheckedEquals(emboss_reserved_local_other.one_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOr(false) &&
+        !has_two_byte().ValueOr(false))
+      return false;
+    if (has_two_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_two_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOr(false) &&
+        has_two_byte().ValueOr(false) &&
+        !two_byte().UncheckedEquals(emboss_reserved_local_other.two_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOr(false) &&
+        !has_three_byte().ValueOr(false))
+      return false;
+    if (has_three_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_three_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOr(false) &&
+        has_three_byte().ValueOr(false) &&
+        !three_byte().UncheckedEquals(emboss_reserved_local_other.three_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOr(false) &&
+        !has_four_byte().ValueOr(false))
+      return false;
+    if (has_four_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_four_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOr(false) &&
+        has_four_byte().ValueOr(false) &&
+        !four_byte().UncheckedEquals(emboss_reserved_local_other.four_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOr(false) &&
+        !has_five_byte().ValueOr(false))
+      return false;
+    if (has_five_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_five_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOr(false) &&
+        has_five_byte().ValueOr(false) &&
+        !five_byte().UncheckedEquals(emboss_reserved_local_other.five_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOr(false) &&
+        !has_six_byte().ValueOr(false))
+      return false;
+    if (has_six_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_six_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOr(false) &&
+        has_six_byte().ValueOr(false) &&
+        !six_byte().UncheckedEquals(emboss_reserved_local_other.six_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOr(false) &&
+        !has_seven_byte().ValueOr(false))
+      return false;
+    if (has_seven_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_seven_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOr(false) &&
+        has_seven_byte().ValueOr(false) &&
+        !seven_byte().UncheckedEquals(emboss_reserved_local_other.seven_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOr(false) &&
+        !has_eight_byte().ValueOr(false))
+      return false;
+    if (has_eight_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_eight_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOr(false) &&
+        has_eight_byte().ValueOr(false) &&
+        !eight_byte().UncheckedEquals(emboss_reserved_local_other.eight_byte()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericAlternatingEndianSizesView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericAlternatingEndianSizesView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericAlternatingEndianSizesView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "one_byte") {
+        if (!one_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "two_byte") {
+        if (!two_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "three_byte") {
+        if (!three_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "four_byte") {
+        if (!four_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "five_byte") {
+        if (!five_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "six_byte") {
+        if (!six_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "seven_byte") {
+        if (!seven_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "eight_byte") {
+        if (!eight_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_one_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          one_byte().IsAggregate() || one_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("one_byte: ");
+        one_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !one_byte().IsAggregate() && !one_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# one_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_two_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          two_byte().IsAggregate() || two_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("two_byte: ");
+        two_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !two_byte().IsAggregate() && !two_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# two_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_three_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          three_byte().IsAggregate() || three_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("three_byte: ");
+        three_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !three_byte().IsAggregate() && !three_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# three_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_four_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          four_byte().IsAggregate() || four_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("four_byte: ");
+        four_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !four_byte().IsAggregate() && !four_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# four_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_five_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          five_byte().IsAggregate() || five_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("five_byte: ");
+        five_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !five_byte().IsAggregate() && !five_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# five_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_six_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          six_byte().IsAggregate() || six_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("six_byte: ");
+        six_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !six_byte().IsAggregate() && !six_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# six_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_seven_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          seven_byte().IsAggregate() || seven_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("seven_byte: ");
+        seven_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !seven_byte().IsAggregate() && !seven_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# seven_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_eight_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          eight_byte().IsAggregate() || eight_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("eight_byte: ");
+        eight_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !eight_byte().IsAggregate() && !eight_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# eight_byte: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ one_byte() const;
+  ::emboss::support::Maybe<bool> has_one_byte() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+ two_byte() const;
+  ::emboss::support::Maybe<bool> has_two_byte() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+ three_byte() const;
+  ::emboss::support::Maybe<bool> has_three_byte() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+ four_byte() const;
+  ::emboss::support::Maybe<bool> has_four_byte() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 40>>
+
+ five_byte() const;
+  ::emboss::support::Maybe<bool> has_five_byte() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 15>>, 48>>
+
+ six_byte() const;
+  ::emboss::support::Maybe<bool> has_six_byte() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 56>>
+
+ seven_byte() const;
+  ::emboss::support::Maybe<bool> has_seven_byte() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 28>>, 64>>
+
+ eight_byte() const;
+  ::emboss::support::Maybe<bool> has_eight_byte() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericAlternatingEndianSizesView;
+};
+using AlternatingEndianSizesView =
+    GenericAlternatingEndianSizesView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using AlternatingEndianSizesWriter =
+    GenericAlternatingEndianSizesView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericAlternatingEndianSizesView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericAlternatingEndianSizesView<
+    GenericAlternatingEndianSizesView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericAlternatingEndianSizesView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeAlternatingEndianSizesView( T &&emboss_reserved_local_arg) {
+  return GenericAlternatingEndianSizesView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericAlternatingEndianSizesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeAlternatingEndianSizesView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericAlternatingEndianSizesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericAlternatingEndianSizesView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedAlternatingEndianSizesView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericAlternatingEndianSizesView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+
+
+
+
+
+namespace EnumSizes {
+
+}  // namespace EnumSizes
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericEnumSizesView;
+
+template <class Storage>
+class GenericEnumSizesView final {
+ public:
+  GenericEnumSizesView() : backing_() {}
+  explicit GenericEnumSizesView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEnumSizesView(
+      const GenericEnumSizesView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericEnumSizesView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericEnumSizesView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericEnumSizesView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEnumSizesView<Storage> &operator=(
+      const GenericEnumSizesView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_one_byte().Known()) return false;
+    if (has_one_byte().ValueOrDefault() && !one_byte().Ok()) return false;
+
+
+    if (!has_two_byte().Known()) return false;
+    if (has_two_byte().ValueOrDefault() && !two_byte().Ok()) return false;
+
+
+    if (!has_three_byte().Known()) return false;
+    if (has_three_byte().ValueOrDefault() && !three_byte().Ok()) return false;
+
+
+    if (!has_four_byte().Known()) return false;
+    if (has_four_byte().ValueOrDefault() && !four_byte().Ok()) return false;
+
+
+    if (!has_five_byte().Known()) return false;
+    if (has_five_byte().ValueOrDefault() && !five_byte().Ok()) return false;
+
+
+    if (!has_six_byte().Known()) return false;
+    if (has_six_byte().ValueOrDefault() && !six_byte().Ok()) return false;
+
+
+    if (!has_seven_byte().Known()) return false;
+    if (has_seven_byte().ValueOrDefault() && !seven_byte().Ok()) return false;
+
+
+    if (!has_eight_byte().Known()) return false;
+    if (has_eight_byte().ValueOrDefault() && !eight_byte().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericEnumSizesView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_one_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_one_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOrDefault() &&
+        !has_one_byte().ValueOrDefault())
+      return false;
+    if (has_one_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_one_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOrDefault() &&
+        has_one_byte().ValueOrDefault() &&
+        !one_byte().Equals(emboss_reserved_local_other.one_byte()))
+      return false;
+
+
+
+    if (!has_two_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_two_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOrDefault() &&
+        !has_two_byte().ValueOrDefault())
+      return false;
+    if (has_two_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_two_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOrDefault() &&
+        has_two_byte().ValueOrDefault() &&
+        !two_byte().Equals(emboss_reserved_local_other.two_byte()))
+      return false;
+
+
+
+    if (!has_three_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_three_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOrDefault() &&
+        !has_three_byte().ValueOrDefault())
+      return false;
+    if (has_three_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_three_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOrDefault() &&
+        has_three_byte().ValueOrDefault() &&
+        !three_byte().Equals(emboss_reserved_local_other.three_byte()))
+      return false;
+
+
+
+    if (!has_four_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_four_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOrDefault() &&
+        !has_four_byte().ValueOrDefault())
+      return false;
+    if (has_four_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_four_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOrDefault() &&
+        has_four_byte().ValueOrDefault() &&
+        !four_byte().Equals(emboss_reserved_local_other.four_byte()))
+      return false;
+
+
+
+    if (!has_five_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_five_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOrDefault() &&
+        !has_five_byte().ValueOrDefault())
+      return false;
+    if (has_five_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_five_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOrDefault() &&
+        has_five_byte().ValueOrDefault() &&
+        !five_byte().Equals(emboss_reserved_local_other.five_byte()))
+      return false;
+
+
+
+    if (!has_six_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_six_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOrDefault() &&
+        !has_six_byte().ValueOrDefault())
+      return false;
+    if (has_six_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_six_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOrDefault() &&
+        has_six_byte().ValueOrDefault() &&
+        !six_byte().Equals(emboss_reserved_local_other.six_byte()))
+      return false;
+
+
+
+    if (!has_seven_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_seven_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOrDefault() &&
+        !has_seven_byte().ValueOrDefault())
+      return false;
+    if (has_seven_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_seven_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOrDefault() &&
+        has_seven_byte().ValueOrDefault() &&
+        !seven_byte().Equals(emboss_reserved_local_other.seven_byte()))
+      return false;
+
+
+
+    if (!has_eight_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_eight_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOrDefault() &&
+        !has_eight_byte().ValueOrDefault())
+      return false;
+    if (has_eight_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_eight_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOrDefault() &&
+        has_eight_byte().ValueOrDefault() &&
+        !eight_byte().Equals(emboss_reserved_local_other.eight_byte()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericEnumSizesView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_one_byte().ValueOr(false) &&
+        !has_one_byte().ValueOr(false))
+      return false;
+    if (has_one_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_one_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOr(false) &&
+        has_one_byte().ValueOr(false) &&
+        !one_byte().UncheckedEquals(emboss_reserved_local_other.one_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOr(false) &&
+        !has_two_byte().ValueOr(false))
+      return false;
+    if (has_two_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_two_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOr(false) &&
+        has_two_byte().ValueOr(false) &&
+        !two_byte().UncheckedEquals(emboss_reserved_local_other.two_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOr(false) &&
+        !has_three_byte().ValueOr(false))
+      return false;
+    if (has_three_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_three_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOr(false) &&
+        has_three_byte().ValueOr(false) &&
+        !three_byte().UncheckedEquals(emboss_reserved_local_other.three_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOr(false) &&
+        !has_four_byte().ValueOr(false))
+      return false;
+    if (has_four_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_four_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOr(false) &&
+        has_four_byte().ValueOr(false) &&
+        !four_byte().UncheckedEquals(emboss_reserved_local_other.four_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOr(false) &&
+        !has_five_byte().ValueOr(false))
+      return false;
+    if (has_five_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_five_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOr(false) &&
+        has_five_byte().ValueOr(false) &&
+        !five_byte().UncheckedEquals(emboss_reserved_local_other.five_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOr(false) &&
+        !has_six_byte().ValueOr(false))
+      return false;
+    if (has_six_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_six_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOr(false) &&
+        has_six_byte().ValueOr(false) &&
+        !six_byte().UncheckedEquals(emboss_reserved_local_other.six_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOr(false) &&
+        !has_seven_byte().ValueOr(false))
+      return false;
+    if (has_seven_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_seven_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOr(false) &&
+        has_seven_byte().ValueOr(false) &&
+        !seven_byte().UncheckedEquals(emboss_reserved_local_other.seven_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOr(false) &&
+        !has_eight_byte().ValueOr(false))
+      return false;
+    if (has_eight_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_eight_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOr(false) &&
+        has_eight_byte().ValueOr(false) &&
+        !eight_byte().UncheckedEquals(emboss_reserved_local_other.eight_byte()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericEnumSizesView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericEnumSizesView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericEnumSizesView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "one_byte") {
+        if (!one_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "two_byte") {
+        if (!two_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "three_byte") {
+        if (!three_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "four_byte") {
+        if (!four_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "five_byte") {
+        if (!five_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "six_byte") {
+        if (!six_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "seven_byte") {
+        if (!seven_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "eight_byte") {
+        if (!eight_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_one_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          one_byte().IsAggregate() || one_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("one_byte: ");
+        one_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !one_byte().IsAggregate() && !one_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# one_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_two_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          two_byte().IsAggregate() || two_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("two_byte: ");
+        two_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !two_byte().IsAggregate() && !two_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# two_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_three_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          three_byte().IsAggregate() || three_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("three_byte: ");
+        three_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !three_byte().IsAggregate() && !three_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# three_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_four_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          four_byte().IsAggregate() || four_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("four_byte: ");
+        four_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !four_byte().IsAggregate() && !four_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# four_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_five_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          five_byte().IsAggregate() || five_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("five_byte: ");
+        five_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !five_byte().IsAggregate() && !five_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# five_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_six_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          six_byte().IsAggregate() || six_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("six_byte: ");
+        six_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !six_byte().IsAggregate() && !six_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# six_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_seven_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          seven_byte().IsAggregate() || seven_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("seven_byte: ");
+        seven_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !seven_byte().IsAggregate() && !seven_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# seven_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_eight_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          eight_byte().IsAggregate() || eight_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("eight_byte: ");
+        eight_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !eight_byte().IsAggregate() && !eight_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# eight_byte: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ one_byte() const;
+  ::emboss::support::Maybe<bool> has_one_byte() const;
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+ two_byte() const;
+  ::emboss::support::Maybe<bool> has_two_byte() const;
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+ three_byte() const;
+  ::emboss::support::Maybe<bool> has_three_byte() const;
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+ four_byte() const;
+  ::emboss::support::Maybe<bool> has_four_byte() const;
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 40>>
+
+ five_byte() const;
+  ::emboss::support::Maybe<bool> has_five_byte() const;
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 15>>, 48>>
+
+ six_byte() const;
+  ::emboss::support::Maybe<bool> has_six_byte() const;
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 56>>
+
+ seven_byte() const;
+  ::emboss::support::Maybe<bool> has_seven_byte() const;
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 28>>, 64>>
+
+ eight_byte() const;
+  ::emboss::support::Maybe<bool> has_eight_byte() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericEnumSizesView;
+};
+using EnumSizesView =
+    GenericEnumSizesView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using EnumSizesWriter =
+    GenericEnumSizesView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericEnumSizesView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericEnumSizesView<
+    GenericEnumSizesView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericEnumSizesView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeEnumSizesView( T &&emboss_reserved_local_arg) {
+  return GenericEnumSizesView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericEnumSizesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeEnumSizesView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericEnumSizesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericEnumSizesView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedEnumSizesView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericEnumSizesView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+
+
+namespace ExplicitlySizedEnumSizes {
+
+
+
+namespace EmbossReservedAnonymousField1 {
+
+}  // namespace EmbossReservedAnonymousField1
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View;
+
+template <class Storage>
+class GenericEmbossReservedAnonymousField1View final {
+ public:
+  GenericEmbossReservedAnonymousField1View() : backing_() {}
+  explicit GenericEmbossReservedAnonymousField1View(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEmbossReservedAnonymousField1View(
+      const GenericEmbossReservedAnonymousField1View<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericEmbossReservedAnonymousField1View(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericEmbossReservedAnonymousField1View(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericEmbossReservedAnonymousField1View<Storage> &operator=(
+      const GenericEmbossReservedAnonymousField1View<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_three_and_a_half_byte().Known()) return false;
+    if (has_three_and_a_half_byte().ValueOrDefault() && !three_and_a_half_byte().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBits().Known()) return false;
+    if (has_IntrinsicSizeInBits().ValueOrDefault() && !IntrinsicSizeInBits().Ok()) return false;
+
+
+    if (!has_MaxSizeInBits().Known()) return false;
+    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok()) return false;
+
+
+    if (!has_MinSizeInBits().Known()) return false;
+    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBits().Ok() &&
+           backing_.SizeInBits() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBits().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBits() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBits().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBits().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_three_and_a_half_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_three_and_a_half_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_three_and_a_half_byte().ValueOrDefault() &&
+        !has_three_and_a_half_byte().ValueOrDefault())
+      return false;
+    if (has_three_and_a_half_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_three_and_a_half_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_three_and_a_half_byte().ValueOrDefault() &&
+        has_three_and_a_half_byte().ValueOrDefault() &&
+        !three_and_a_half_byte().Equals(emboss_reserved_local_other.three_and_a_half_byte()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_three_and_a_half_byte().ValueOr(false) &&
+        !has_three_and_a_half_byte().ValueOr(false))
+      return false;
+    if (has_three_and_a_half_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_three_and_a_half_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_three_and_a_half_byte().ValueOr(false) &&
+        has_three_and_a_half_byte().ValueOr(false) &&
+        !three_and_a_half_byte().UncheckedEquals(emboss_reserved_local_other.three_and_a_half_byte()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericEmbossReservedAnonymousField1View<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "three_and_a_half_byte") {
+        if (!three_and_a_half_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_three_and_a_half_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          three_and_a_half_byte().IsAggregate() || three_and_a_half_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("three_and_a_half_byte: ");
+        three_and_a_half_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !three_and_a_half_byte().IsAggregate() && !three_and_a_half_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# three_and_a_half_byte: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::ExplicitlySizedEnum,
+    ::emboss::support::FixedSizeViewParameters<28, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ three_and_a_half_byte() const;
+  ::emboss::support::Maybe<bool> has_three_and_a_half_byte() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView IntrinsicSizeInBits() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBitsView() {}
+    EmbossReservedDollarVirtualMaxSizeInBitsView(const EmbossReservedDollarVirtualMaxSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView(EmbossReservedDollarVirtualMaxSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(const EmbossReservedDollarVirtualMaxSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(EmbossReservedDollarVirtualMaxSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBitsView MaxSizeInBits() {
+    return EmbossReservedDollarVirtualMaxSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBitsView() {}
+    EmbossReservedDollarVirtualMinSizeInBitsView(const EmbossReservedDollarVirtualMinSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView(EmbossReservedDollarVirtualMinSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(const EmbossReservedDollarVirtualMinSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(EmbossReservedDollarVirtualMinSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBitsView MinSizeInBits() {
+    return EmbossReservedDollarVirtualMinSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericEmbossReservedAnonymousField1View;
+};
+using EmbossReservedAnonymousField1View =
+    GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using EmbossReservedAnonymousField1Writer =
+    GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View<
+    GenericEmbossReservedAnonymousField1View<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericEmbossReservedAnonymousField1View<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeEmbossReservedAnonymousField1View( T &&emboss_reserved_local_arg) {
+  return GenericEmbossReservedAnonymousField1View<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeEmbossReservedAnonymousField1View( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericEmbossReservedAnonymousField1View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericEmbossReservedAnonymousField1View<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedEmbossReservedAnonymousField1View(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericEmbossReservedAnonymousField1View<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+}  // namespace ExplicitlySizedEnumSizes
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericExplicitlySizedEnumSizesView;
+
+template <class Storage>
+class GenericExplicitlySizedEnumSizesView final {
+ public:
+  GenericExplicitlySizedEnumSizesView() : backing_() {}
+  explicit GenericExplicitlySizedEnumSizesView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericExplicitlySizedEnumSizesView(
+      const GenericExplicitlySizedEnumSizesView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericExplicitlySizedEnumSizesView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericExplicitlySizedEnumSizesView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericExplicitlySizedEnumSizesView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericExplicitlySizedEnumSizesView<Storage> &operator=(
+      const GenericExplicitlySizedEnumSizesView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_one_byte().Known()) return false;
+    if (has_one_byte().ValueOrDefault() && !one_byte().Ok()) return false;
+
+
+    if (!has_two_byte().Known()) return false;
+    if (has_two_byte().ValueOrDefault() && !two_byte().Ok()) return false;
+
+
+    if (!has_three_byte().Known()) return false;
+    if (has_three_byte().ValueOrDefault() && !three_byte().Ok()) return false;
+
+
+    if (!has_emboss_reserved_anonymous_field_1().Known()) return false;
+    if (has_emboss_reserved_anonymous_field_1().ValueOrDefault() && !emboss_reserved_anonymous_field_1().Ok()) return false;
+
+
+    if (!has_three_and_a_half_byte().Known()) return false;
+    if (has_three_and_a_half_byte().ValueOrDefault() && !three_and_a_half_byte().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericExplicitlySizedEnumSizesView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_one_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_one_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOrDefault() &&
+        !has_one_byte().ValueOrDefault())
+      return false;
+    if (has_one_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_one_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOrDefault() &&
+        has_one_byte().ValueOrDefault() &&
+        !one_byte().Equals(emboss_reserved_local_other.one_byte()))
+      return false;
+
+
+
+    if (!has_two_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_two_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOrDefault() &&
+        !has_two_byte().ValueOrDefault())
+      return false;
+    if (has_two_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_two_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOrDefault() &&
+        has_two_byte().ValueOrDefault() &&
+        !two_byte().Equals(emboss_reserved_local_other.two_byte()))
+      return false;
+
+
+
+    if (!has_three_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_three_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOrDefault() &&
+        !has_three_byte().ValueOrDefault())
+      return false;
+    if (has_three_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_three_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOrDefault() &&
+        has_three_byte().ValueOrDefault() &&
+        !three_byte().Equals(emboss_reserved_local_other.three_byte()))
+      return false;
+
+
+
+    if (!has_emboss_reserved_anonymous_field_1().Known()) return false;
+    if (!emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().Known()) return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        !has_emboss_reserved_anonymous_field_1().ValueOrDefault())
+      return false;
+    if (has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
+        !emboss_reserved_anonymous_field_1().Equals(emboss_reserved_local_other.emboss_reserved_anonymous_field_1()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericExplicitlySizedEnumSizesView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_one_byte().ValueOr(false) &&
+        !has_one_byte().ValueOr(false))
+      return false;
+    if (has_one_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_one_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOr(false) &&
+        has_one_byte().ValueOr(false) &&
+        !one_byte().UncheckedEquals(emboss_reserved_local_other.one_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOr(false) &&
+        !has_two_byte().ValueOr(false))
+      return false;
+    if (has_two_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_two_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOr(false) &&
+        has_two_byte().ValueOr(false) &&
+        !two_byte().UncheckedEquals(emboss_reserved_local_other.two_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOr(false) &&
+        !has_three_byte().ValueOr(false))
+      return false;
+    if (has_three_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_three_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOr(false) &&
+        has_three_byte().ValueOr(false) &&
+        !three_byte().UncheckedEquals(emboss_reserved_local_other.three_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        !has_emboss_reserved_anonymous_field_1().ValueOr(false))
+      return false;
+    if (has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        !emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
+        !emboss_reserved_anonymous_field_1().UncheckedEquals(emboss_reserved_local_other.emboss_reserved_anonymous_field_1()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericExplicitlySizedEnumSizesView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericExplicitlySizedEnumSizesView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericExplicitlySizedEnumSizesView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "one_byte") {
+        if (!one_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "two_byte") {
+        if (!two_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "three_byte") {
+        if (!three_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "three_and_a_half_byte") {
+        if (!three_and_a_half_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_one_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          one_byte().IsAggregate() || one_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("one_byte: ");
+        one_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !one_byte().IsAggregate() && !one_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# one_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_two_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          two_byte().IsAggregate() || two_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("two_byte: ");
+        two_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !two_byte().IsAggregate() && !two_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# two_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_three_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          three_byte().IsAggregate() || three_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("three_byte: ");
+        three_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !three_byte().IsAggregate() && !three_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# three_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_three_and_a_half_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          three_and_a_half_byte().IsAggregate() || three_and_a_half_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("three_and_a_half_byte: ");
+        three_and_a_half_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !three_and_a_half_byte().IsAggregate() && !three_and_a_half_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# three_and_a_half_byte: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::ExplicitlySizedEnum,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ one_byte() const;
+  ::emboss::support::Maybe<bool> has_one_byte() const;
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::ExplicitlySizedEnum,
+    ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+ two_byte() const;
+  ::emboss::support::Maybe<bool> has_two_byte() const;
+
+ public:
+  typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::ExplicitlySizedEnum,
+    ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+ three_byte() const;
+  ::emboss::support::Maybe<bool> has_three_byte() const;
+
+ private:
+  typename ::emboss::test::ExplicitlySizedEnumSizes::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+ emboss_reserved_anonymous_field_1() const;
+  ::emboss::support::Maybe<bool> has_emboss_reserved_anonymous_field_1() const;
+
+ public:
+  auto three_and_a_half_byte() const -> decltype(this->emboss_reserved_anonymous_field_1().three_and_a_half_byte()) {
+   return has_three_and_a_half_byte().ValueOrDefault() ? emboss_reserved_anonymous_field_1().three_and_a_half_byte()
+                                          : decltype(this->emboss_reserved_anonymous_field_1().three_and_a_half_byte())();
+  }
+  ::emboss::support::Maybe<bool> has_three_and_a_half_byte() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericExplicitlySizedEnumSizesView;
+};
+using ExplicitlySizedEnumSizesView =
+    GenericExplicitlySizedEnumSizesView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ExplicitlySizedEnumSizesWriter =
+    GenericExplicitlySizedEnumSizesView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericExplicitlySizedEnumSizesView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericExplicitlySizedEnumSizesView<
+    GenericExplicitlySizedEnumSizesView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericExplicitlySizedEnumSizesView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeExplicitlySizedEnumSizesView( T &&emboss_reserved_local_arg) {
+  return GenericExplicitlySizedEnumSizesView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericExplicitlySizedEnumSizesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeExplicitlySizedEnumSizesView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericExplicitlySizedEnumSizesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericExplicitlySizedEnumSizesView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedExplicitlySizedEnumSizesView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericExplicitlySizedEnumSizesView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+enum class Enum : ::std::uint64_t {
+  VALUE1 = static_cast</**/::std::int32_t>(1LL),
+  VALUE10 = static_cast</**/::std::int32_t>(10LL),
+  VALUE100 = static_cast</**/::std::int32_t>(100LL),
+  VALUE1000 = static_cast</**/::std::int32_t>(1000LL),
+  VALUE10000 = static_cast</**/::std::int32_t>(10000LL),
+  VALUE100000 = static_cast</**/::std::int32_t>(100000LL),
+  VALUE1000000 = static_cast</**/::std::int32_t>(1000000LL),
+  VALUE10000000 = static_cast</**/::std::int32_t>(10000000LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<Enum> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   Enum *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("VALUE1", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Enum::VALUE1;
+      return true;
+    }
+
+    if (!strcmp("VALUE10", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Enum::VALUE10;
+      return true;
+    }
+
+    if (!strcmp("VALUE100", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Enum::VALUE100;
+      return true;
+    }
+
+    if (!strcmp("VALUE1000", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Enum::VALUE1000;
+      return true;
+    }
+
+    if (!strcmp("VALUE10000", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Enum::VALUE10000;
+      return true;
+    }
+
+    if (!strcmp("VALUE100000", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Enum::VALUE100000;
+      return true;
+    }
+
+    if (!strcmp("VALUE1000000", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Enum::VALUE1000000;
+      return true;
+    }
+
+    if (!strcmp("VALUE10000000", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Enum::VALUE10000000;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      Enum emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Enum::VALUE1: return "VALUE1";
+
+      case Enum::VALUE10: return "VALUE10";
+
+      case Enum::VALUE100: return "VALUE100";
+
+      case Enum::VALUE1000: return "VALUE1000";
+
+      case Enum::VALUE10000: return "VALUE10000";
+
+      case Enum::VALUE100000: return "VALUE100000";
+
+      case Enum::VALUE1000000: return "VALUE1000000";
+
+      case Enum::VALUE10000000: return "VALUE10000000";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(Enum emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Enum::VALUE1: return true;
+
+      case Enum::VALUE10: return true;
+
+      case Enum::VALUE100: return true;
+
+      case Enum::VALUE1000: return true;
+
+      case Enum::VALUE10000: return true;
+
+      case Enum::VALUE100000: return true;
+
+      case Enum::VALUE1000000: return true;
+
+      case Enum::VALUE10000000: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       Enum emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<Enum>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    Enum *emboss_reserved_local_result) {
+  return EnumTraits<Enum>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    Enum emboss_reserved_local_value) {
+  return EnumTraits<Enum>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(Enum emboss_reserved_local_value) {
+  return EnumTraits<Enum>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    Enum emboss_reserved_local_value) {
+  return EnumTraits<Enum>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+enum class ExplicitlySizedEnum : ::std::uint32_t {
+  VALUE1 = static_cast</**/::std::int32_t>(1LL),
+  VALUE10 = static_cast</**/::std::int32_t>(10LL),
+  VALUE100 = static_cast</**/::std::int32_t>(100LL),
+  VALUE1000 = static_cast</**/::std::int32_t>(1000LL),
+  VALUE10000 = static_cast</**/::std::int32_t>(10000LL),
+  VALUE100000 = static_cast</**/::std::int32_t>(100000LL),
+  VALUE1000000 = static_cast</**/::std::int32_t>(1000000LL),
+  VALUE10000000 = static_cast</**/::std::int32_t>(10000000LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<ExplicitlySizedEnum> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   ExplicitlySizedEnum *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("VALUE1", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = ExplicitlySizedEnum::VALUE1;
+      return true;
+    }
+
+    if (!strcmp("VALUE10", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = ExplicitlySizedEnum::VALUE10;
+      return true;
+    }
+
+    if (!strcmp("VALUE100", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = ExplicitlySizedEnum::VALUE100;
+      return true;
+    }
+
+    if (!strcmp("VALUE1000", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = ExplicitlySizedEnum::VALUE1000;
+      return true;
+    }
+
+    if (!strcmp("VALUE10000", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = ExplicitlySizedEnum::VALUE10000;
+      return true;
+    }
+
+    if (!strcmp("VALUE100000", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = ExplicitlySizedEnum::VALUE100000;
+      return true;
+    }
+
+    if (!strcmp("VALUE1000000", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = ExplicitlySizedEnum::VALUE1000000;
+      return true;
+    }
+
+    if (!strcmp("VALUE10000000", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = ExplicitlySizedEnum::VALUE10000000;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      ExplicitlySizedEnum emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case ExplicitlySizedEnum::VALUE1: return "VALUE1";
+
+      case ExplicitlySizedEnum::VALUE10: return "VALUE10";
+
+      case ExplicitlySizedEnum::VALUE100: return "VALUE100";
+
+      case ExplicitlySizedEnum::VALUE1000: return "VALUE1000";
+
+      case ExplicitlySizedEnum::VALUE10000: return "VALUE10000";
+
+      case ExplicitlySizedEnum::VALUE100000: return "VALUE100000";
+
+      case ExplicitlySizedEnum::VALUE1000000: return "VALUE1000000";
+
+      case ExplicitlySizedEnum::VALUE10000000: return "VALUE10000000";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(ExplicitlySizedEnum emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case ExplicitlySizedEnum::VALUE1: return true;
+
+      case ExplicitlySizedEnum::VALUE10: return true;
+
+      case ExplicitlySizedEnum::VALUE100: return true;
+
+      case ExplicitlySizedEnum::VALUE1000: return true;
+
+      case ExplicitlySizedEnum::VALUE10000: return true;
+
+      case ExplicitlySizedEnum::VALUE100000: return true;
+
+      case ExplicitlySizedEnum::VALUE1000000: return true;
+
+      case ExplicitlySizedEnum::VALUE10000000: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       ExplicitlySizedEnum emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<ExplicitlySizedEnum>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    ExplicitlySizedEnum *emboss_reserved_local_result) {
+  return EnumTraits<ExplicitlySizedEnum>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    ExplicitlySizedEnum emboss_reserved_local_value) {
+  return EnumTraits<ExplicitlySizedEnum>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(ExplicitlySizedEnum emboss_reserved_local_value) {
+  return EnumTraits<ExplicitlySizedEnum>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    ExplicitlySizedEnum emboss_reserved_local_value) {
+  return EnumTraits<ExplicitlySizedEnum>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+
+
+
+
+
+
+
+
+
+
+namespace ArraySizes {
+
+}  // namespace ArraySizes
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericArraySizesView;
+
+template <class Storage>
+class GenericArraySizesView final {
+ public:
+  GenericArraySizesView() : backing_() {}
+  explicit GenericArraySizesView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericArraySizesView(
+      const GenericArraySizesView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericArraySizesView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericArraySizesView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericArraySizesView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericArraySizesView<Storage> &operator=(
+      const GenericArraySizesView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_one_byte().Known()) return false;
+    if (has_one_byte().ValueOrDefault() && !one_byte().Ok()) return false;
+
+
+    if (!has_two_byte().Known()) return false;
+    if (has_two_byte().ValueOrDefault() && !two_byte().Ok()) return false;
+
+
+    if (!has_three_byte().Known()) return false;
+    if (has_three_byte().ValueOrDefault() && !three_byte().Ok()) return false;
+
+
+    if (!has_four_byte().Known()) return false;
+    if (has_four_byte().ValueOrDefault() && !four_byte().Ok()) return false;
+
+
+    if (!has_five_byte().Known()) return false;
+    if (has_five_byte().ValueOrDefault() && !five_byte().Ok()) return false;
+
+
+    if (!has_six_byte().Known()) return false;
+    if (has_six_byte().ValueOrDefault() && !six_byte().Ok()) return false;
+
+
+    if (!has_seven_byte().Known()) return false;
+    if (has_seven_byte().ValueOrDefault() && !seven_byte().Ok()) return false;
+
+
+    if (!has_eight_byte().Known()) return false;
+    if (has_eight_byte().ValueOrDefault() && !eight_byte().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericArraySizesView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_one_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_one_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOrDefault() &&
+        !has_one_byte().ValueOrDefault())
+      return false;
+    if (has_one_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_one_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOrDefault() &&
+        has_one_byte().ValueOrDefault() &&
+        !one_byte().Equals(emboss_reserved_local_other.one_byte()))
+      return false;
+
+
+
+    if (!has_two_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_two_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOrDefault() &&
+        !has_two_byte().ValueOrDefault())
+      return false;
+    if (has_two_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_two_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOrDefault() &&
+        has_two_byte().ValueOrDefault() &&
+        !two_byte().Equals(emboss_reserved_local_other.two_byte()))
+      return false;
+
+
+
+    if (!has_three_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_three_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOrDefault() &&
+        !has_three_byte().ValueOrDefault())
+      return false;
+    if (has_three_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_three_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOrDefault() &&
+        has_three_byte().ValueOrDefault() &&
+        !three_byte().Equals(emboss_reserved_local_other.three_byte()))
+      return false;
+
+
+
+    if (!has_four_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_four_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOrDefault() &&
+        !has_four_byte().ValueOrDefault())
+      return false;
+    if (has_four_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_four_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOrDefault() &&
+        has_four_byte().ValueOrDefault() &&
+        !four_byte().Equals(emboss_reserved_local_other.four_byte()))
+      return false;
+
+
+
+    if (!has_five_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_five_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOrDefault() &&
+        !has_five_byte().ValueOrDefault())
+      return false;
+    if (has_five_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_five_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOrDefault() &&
+        has_five_byte().ValueOrDefault() &&
+        !five_byte().Equals(emboss_reserved_local_other.five_byte()))
+      return false;
+
+
+
+    if (!has_six_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_six_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOrDefault() &&
+        !has_six_byte().ValueOrDefault())
+      return false;
+    if (has_six_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_six_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOrDefault() &&
+        has_six_byte().ValueOrDefault() &&
+        !six_byte().Equals(emboss_reserved_local_other.six_byte()))
+      return false;
+
+
+
+    if (!has_seven_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_seven_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOrDefault() &&
+        !has_seven_byte().ValueOrDefault())
+      return false;
+    if (has_seven_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_seven_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOrDefault() &&
+        has_seven_byte().ValueOrDefault() &&
+        !seven_byte().Equals(emboss_reserved_local_other.seven_byte()))
+      return false;
+
+
+
+    if (!has_eight_byte().Known()) return false;
+    if (!emboss_reserved_local_other.has_eight_byte().Known()) return false;
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOrDefault() &&
+        !has_eight_byte().ValueOrDefault())
+      return false;
+    if (has_eight_byte().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_eight_byte().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOrDefault() &&
+        has_eight_byte().ValueOrDefault() &&
+        !eight_byte().Equals(emboss_reserved_local_other.eight_byte()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericArraySizesView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_one_byte().ValueOr(false) &&
+        !has_one_byte().ValueOr(false))
+      return false;
+    if (has_one_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_one_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_one_byte().ValueOr(false) &&
+        has_one_byte().ValueOr(false) &&
+        !one_byte().UncheckedEquals(emboss_reserved_local_other.one_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOr(false) &&
+        !has_two_byte().ValueOr(false))
+      return false;
+    if (has_two_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_two_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_two_byte().ValueOr(false) &&
+        has_two_byte().ValueOr(false) &&
+        !two_byte().UncheckedEquals(emboss_reserved_local_other.two_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOr(false) &&
+        !has_three_byte().ValueOr(false))
+      return false;
+    if (has_three_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_three_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_three_byte().ValueOr(false) &&
+        has_three_byte().ValueOr(false) &&
+        !three_byte().UncheckedEquals(emboss_reserved_local_other.three_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOr(false) &&
+        !has_four_byte().ValueOr(false))
+      return false;
+    if (has_four_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_four_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_four_byte().ValueOr(false) &&
+        has_four_byte().ValueOr(false) &&
+        !four_byte().UncheckedEquals(emboss_reserved_local_other.four_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOr(false) &&
+        !has_five_byte().ValueOr(false))
+      return false;
+    if (has_five_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_five_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_five_byte().ValueOr(false) &&
+        has_five_byte().ValueOr(false) &&
+        !five_byte().UncheckedEquals(emboss_reserved_local_other.five_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOr(false) &&
+        !has_six_byte().ValueOr(false))
+      return false;
+    if (has_six_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_six_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_six_byte().ValueOr(false) &&
+        has_six_byte().ValueOr(false) &&
+        !six_byte().UncheckedEquals(emboss_reserved_local_other.six_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOr(false) &&
+        !has_seven_byte().ValueOr(false))
+      return false;
+    if (has_seven_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_seven_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_seven_byte().ValueOr(false) &&
+        has_seven_byte().ValueOr(false) &&
+        !seven_byte().UncheckedEquals(emboss_reserved_local_other.seven_byte()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOr(false) &&
+        !has_eight_byte().ValueOr(false))
+      return false;
+    if (has_eight_byte().ValueOr(false) &&
+        !emboss_reserved_local_other.has_eight_byte().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_eight_byte().ValueOr(false) &&
+        has_eight_byte().ValueOr(false) &&
+        !eight_byte().UncheckedEquals(emboss_reserved_local_other.eight_byte()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericArraySizesView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericArraySizesView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericArraySizesView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "one_byte") {
+        if (!one_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "two_byte") {
+        if (!two_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "three_byte") {
+        if (!three_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "four_byte") {
+        if (!four_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "five_byte") {
+        if (!five_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "six_byte") {
+        if (!six_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "seven_byte") {
+        if (!seven_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "eight_byte") {
+        if (!eight_byte().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_one_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          one_byte().IsAggregate() || one_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("one_byte: ");
+        one_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !one_byte().IsAggregate() && !one_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# one_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_two_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          two_byte().IsAggregate() || two_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("two_byte: ");
+        two_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !two_byte().IsAggregate() && !two_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# two_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_three_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          three_byte().IsAggregate() || three_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("three_byte: ");
+        three_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !three_byte().IsAggregate() && !three_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# three_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_four_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          four_byte().IsAggregate() || four_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("four_byte: ");
+        four_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !four_byte().IsAggregate() && !four_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# four_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_five_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          five_byte().IsAggregate() || five_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("five_byte: ");
+        five_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !five_byte().IsAggregate() && !five_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# five_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_six_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          six_byte().IsAggregate() || six_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("six_byte: ");
+        six_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !six_byte().IsAggregate() && !six_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# six_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_seven_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          seven_byte().IsAggregate() || seven_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("seven_byte: ");
+        seven_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !seven_byte().IsAggregate() && !seven_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# seven_byte: UNREADABLE\n");
+      }
+    }
+
+    if (has_eight_byte().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          eight_byte().IsAggregate() || eight_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("eight_byte: ");
+        eight_byte().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !eight_byte().IsAggregate() && !eight_byte().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# eight_byte: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 1,
+    8 >
+
+ one_byte() const;
+  ::emboss::support::Maybe<bool> has_one_byte() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>::template OffsetStorageType</**/2, 0>>, 16>>
+
+, typename Storage::template OffsetStorageType</**/0, 2>, 2,
+    8 >
+
+ two_byte() const;
+  ::emboss::support::Maybe<bool> has_two_byte() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>::template OffsetStorageType</**/3, 0>>, 24>>
+
+, typename Storage::template OffsetStorageType</**/0, 6>, 3,
+    8 >
+
+ three_byte() const;
+  ::emboss::support::Maybe<bool> has_three_byte() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 12>::template OffsetStorageType</**/4, 0>>, 32>>
+
+, typename Storage::template OffsetStorageType</**/0, 12>, 4,
+    8 >
+
+ four_byte() const;
+  ::emboss::support::Maybe<bool> has_four_byte() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 20>::template OffsetStorageType</**/5, 0>>, 40>>
+
+, typename Storage::template OffsetStorageType</**/0, 20>, 5,
+    8 >
+
+ five_byte() const;
+  ::emboss::support::Maybe<bool> has_five_byte() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 30>::template OffsetStorageType</**/6, 0>>, 48>>
+
+, typename Storage::template OffsetStorageType</**/0, 30>, 6,
+    8 >
+
+ six_byte() const;
+  ::emboss::support::Maybe<bool> has_six_byte() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 42>::template OffsetStorageType</**/7, 0>>, 56>>
+
+, typename Storage::template OffsetStorageType</**/0, 42>, 7,
+    8 >
+
+ seven_byte() const;
+  ::emboss::support::Maybe<bool> has_seven_byte() const;
+
+ public:
+  typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 56>::template OffsetStorageType</**/8, 0>>, 64>>
+
+, typename Storage::template OffsetStorageType</**/0, 56>, 8,
+    8 >
+
+ eight_byte() const;
+  ::emboss::support::Maybe<bool> has_eight_byte() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericArraySizesView;
+};
+using ArraySizesView =
+    GenericArraySizesView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ArraySizesWriter =
+    GenericArraySizesView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericArraySizesView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericArraySizesView<
+    GenericArraySizesView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericArraySizesView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeArraySizesView( T &&emboss_reserved_local_arg) {
+  return GenericArraySizesView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericArraySizesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeArraySizesView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericArraySizesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericArraySizesView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedArraySizesView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericArraySizesView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace Sizes {
+
+}  // namespace Sizes
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericSizesView<Storage>::one_byte()
+    const {
+
+  if ( has_one_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizesView<Storage>::has_one_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+ GenericSizesView<Storage>::two_byte()
+    const {
+
+  if ( has_two_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizesView<Storage>::has_two_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+ GenericSizesView<Storage>::three_byte()
+    const {
+
+  if ( has_three_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   3>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizesView<Storage>::has_three_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+ GenericSizesView<Storage>::four_byte()
+    const {
+
+  if ( has_four_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   6>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizesView<Storage>::has_four_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 40>>
+
+ GenericSizesView<Storage>::five_byte()
+    const {
+
+  if ( has_five_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 40>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   10>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 40>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizesView<Storage>::has_five_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 15>>, 48>>
+
+ GenericSizesView<Storage>::six_byte()
+    const {
+
+  if ( has_six_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(15LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 15>>, 48>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   15>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 15>>, 48>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizesView<Storage>::has_six_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 56>>
+
+ GenericSizesView<Storage>::seven_byte()
+    const {
+
+  if ( has_seven_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(7LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(21LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 56>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   21>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 56>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizesView<Storage>::has_seven_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 28>>, 64>>
+
+ GenericSizesView<Storage>::eight_byte()
+    const {
+
+  if ( has_eight_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(28LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 28>>, 64>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   28>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 28>>, 64>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSizesView<Storage>::has_eight_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Sizes {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(36LL)).ValueOrDefault();
+}
+}  // namespace Sizes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizesView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Sizes::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizesView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Sizes::IntrinsicSizeInBytes();
+}
+
+namespace Sizes {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(36LL)).ValueOrDefault();
+}
+}  // namespace Sizes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizesView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Sizes::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizesView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Sizes::MaxSizeInBytes();
+}
+
+namespace Sizes {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(36LL)).ValueOrDefault();
+}
+}  // namespace Sizes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizesView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Sizes::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSizesView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Sizes::MinSizeInBytes();
+}
+namespace BigEndianSizes {
+
+}  // namespace BigEndianSizes
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericBigEndianSizesView<Storage>::one_byte()
+    const {
+
+  if ( has_one_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBigEndianSizesView<Storage>::has_one_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+ GenericBigEndianSizesView<Storage>::two_byte()
+    const {
+
+  if ( has_two_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBigEndianSizesView<Storage>::has_two_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+ GenericBigEndianSizesView<Storage>::three_byte()
+    const {
+
+  if ( has_three_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   3>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBigEndianSizesView<Storage>::has_three_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+ GenericBigEndianSizesView<Storage>::four_byte()
+    const {
+
+  if ( has_four_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   6>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBigEndianSizesView<Storage>::has_four_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 40>>
+
+ GenericBigEndianSizesView<Storage>::five_byte()
+    const {
+
+  if ( has_five_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 40>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   10>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 40>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBigEndianSizesView<Storage>::has_five_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 15>>, 48>>
+
+ GenericBigEndianSizesView<Storage>::six_byte()
+    const {
+
+  if ( has_six_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(15LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 15>>, 48>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   15>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 15>>, 48>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBigEndianSizesView<Storage>::has_six_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 56>>
+
+ GenericBigEndianSizesView<Storage>::seven_byte()
+    const {
+
+  if ( has_seven_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(7LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(21LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 56>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   21>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 56>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBigEndianSizesView<Storage>::has_seven_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 28>>, 64>>
+
+ GenericBigEndianSizesView<Storage>::eight_byte()
+    const {
+
+  if ( has_eight_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(28LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 28>>, 64>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   28>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 28>>, 64>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBigEndianSizesView<Storage>::has_eight_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace BigEndianSizes {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(36LL)).ValueOrDefault();
+}
+}  // namespace BigEndianSizes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBigEndianSizesView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return BigEndianSizes::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBigEndianSizesView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return BigEndianSizes::IntrinsicSizeInBytes();
+}
+
+namespace BigEndianSizes {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(36LL)).ValueOrDefault();
+}
+}  // namespace BigEndianSizes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBigEndianSizesView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return BigEndianSizes::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBigEndianSizesView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return BigEndianSizes::MaxSizeInBytes();
+}
+
+namespace BigEndianSizes {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(36LL)).ValueOrDefault();
+}
+}  // namespace BigEndianSizes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBigEndianSizesView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return BigEndianSizes::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBigEndianSizesView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return BigEndianSizes::MinSizeInBytes();
+}
+namespace AlternatingEndianSizes {
+
+}  // namespace AlternatingEndianSizes
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericAlternatingEndianSizesView<Storage>::one_byte()
+    const {
+
+  if ( has_one_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAlternatingEndianSizesView<Storage>::has_one_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+ GenericAlternatingEndianSizesView<Storage>::two_byte()
+    const {
+
+  if ( has_two_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAlternatingEndianSizesView<Storage>::has_two_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+ GenericAlternatingEndianSizesView<Storage>::three_byte()
+    const {
+
+  if ( has_three_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   3>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAlternatingEndianSizesView<Storage>::has_three_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+ GenericAlternatingEndianSizesView<Storage>::four_byte()
+    const {
+
+  if ( has_four_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   6>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAlternatingEndianSizesView<Storage>::has_four_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 40>>
+
+ GenericAlternatingEndianSizesView<Storage>::five_byte()
+    const {
+
+  if ( has_five_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 40>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   10>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 40>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAlternatingEndianSizesView<Storage>::has_five_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 15>>, 48>>
+
+ GenericAlternatingEndianSizesView<Storage>::six_byte()
+    const {
+
+  if ( has_six_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(15LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 15>>, 48>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   15>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 15>>, 48>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAlternatingEndianSizesView<Storage>::has_six_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 56>>
+
+ GenericAlternatingEndianSizesView<Storage>::seven_byte()
+    const {
+
+  if ( has_seven_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(7LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(21LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 56>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   21>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::BigEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 56>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAlternatingEndianSizesView<Storage>::has_seven_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 28>>, 64>>
+
+ GenericAlternatingEndianSizesView<Storage>::eight_byte()
+    const {
+
+  if ( has_eight_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(28LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 28>>, 64>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   28>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 28>>, 64>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericAlternatingEndianSizesView<Storage>::has_eight_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace AlternatingEndianSizes {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(36LL)).ValueOrDefault();
+}
+}  // namespace AlternatingEndianSizes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAlternatingEndianSizesView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return AlternatingEndianSizes::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAlternatingEndianSizesView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return AlternatingEndianSizes::IntrinsicSizeInBytes();
+}
+
+namespace AlternatingEndianSizes {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(36LL)).ValueOrDefault();
+}
+}  // namespace AlternatingEndianSizes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAlternatingEndianSizesView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return AlternatingEndianSizes::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAlternatingEndianSizesView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return AlternatingEndianSizes::MaxSizeInBytes();
+}
+
+namespace AlternatingEndianSizes {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(36LL)).ValueOrDefault();
+}
+}  // namespace AlternatingEndianSizes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAlternatingEndianSizesView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return AlternatingEndianSizes::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericAlternatingEndianSizesView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return AlternatingEndianSizes::MinSizeInBytes();
+}
+namespace EnumSizes {
+
+}  // namespace EnumSizes
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericEnumSizesView<Storage>::one_byte()
+    const {
+
+  if ( has_one_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEnumSizesView<Storage>::has_one_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+ GenericEnumSizesView<Storage>::two_byte()
+    const {
+
+  if ( has_two_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEnumSizesView<Storage>::has_two_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+ GenericEnumSizesView<Storage>::three_byte()
+    const {
+
+  if ( has_three_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   3>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEnumSizesView<Storage>::has_three_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+ GenericEnumSizesView<Storage>::four_byte()
+    const {
+
+  if ( has_four_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   6>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEnumSizesView<Storage>::has_four_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 40>>
+
+ GenericEnumSizesView<Storage>::five_byte()
+    const {
+
+  if ( has_five_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 40>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   10>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 40>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEnumSizesView<Storage>::has_five_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 15>>, 48>>
+
+ GenericEnumSizesView<Storage>::six_byte()
+    const {
+
+  if ( has_six_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(15LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 15>>, 48>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   15>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 15>>, 48>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEnumSizesView<Storage>::has_six_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 56>>
+
+ GenericEnumSizesView<Storage>::seven_byte()
+    const {
+
+  if ( has_seven_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(7LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(21LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 56>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   21>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 21>>, 56>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEnumSizesView<Storage>::has_seven_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 28>>, 64>>
+
+ GenericEnumSizesView<Storage>::eight_byte()
+    const {
+
+  if ( has_eight_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(28LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 28>>, 64>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   28>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::Enum,
+    ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 28>>, 64>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEnumSizesView<Storage>::has_eight_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace EnumSizes {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(36LL)).ValueOrDefault();
+}
+}  // namespace EnumSizes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEnumSizesView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return EnumSizes::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEnumSizesView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return EnumSizes::IntrinsicSizeInBytes();
+}
+
+namespace EnumSizes {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(36LL)).ValueOrDefault();
+}
+}  // namespace EnumSizes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEnumSizesView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return EnumSizes::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEnumSizesView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return EnumSizes::MaxSizeInBytes();
+}
+
+namespace EnumSizes {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(36LL)).ValueOrDefault();
+}
+}  // namespace EnumSizes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEnumSizesView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return EnumSizes::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEnumSizesView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return EnumSizes::MinSizeInBytes();
+}
+namespace ExplicitlySizedEnumSizes {
+namespace EmbossReservedAnonymousField1 {
+
+}  // namespace EmbossReservedAnonymousField1
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::ExplicitlySizedEnum,
+    ::emboss::support::FixedSizeViewParameters<28, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericEmbossReservedAnonymousField1View<Storage>::three_and_a_half_byte()
+    const {
+
+  if ( has_three_and_a_half_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(28LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::ExplicitlySizedEnum,
+    ::emboss::support::FixedSizeViewParameters<28, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::ExplicitlySizedEnum,
+    ::emboss::support::FixedSizeViewParameters<28, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericEmbossReservedAnonymousField1View<Storage>::has_three_and_a_half_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace EmbossReservedAnonymousField1 {
+inline constexpr ::std::int32_t IntrinsicSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(28LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField1
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField1::IntrinsicSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField1::IntrinsicSizeInBits();
+}
+
+namespace EmbossReservedAnonymousField1 {
+inline constexpr ::std::int32_t MaxSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(28LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField1
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField1::MaxSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField1::MaxSizeInBits();
+}
+
+namespace EmbossReservedAnonymousField1 {
+inline constexpr ::std::int32_t MinSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(28LL)).ValueOrDefault();
+}
+}  // namespace EmbossReservedAnonymousField1
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
+  return EmbossReservedAnonymousField1::MinSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericEmbossReservedAnonymousField1View<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
+  return EmbossReservedAnonymousField1::MinSizeInBits();
+}
+
+}  // namespace ExplicitlySizedEnumSizes
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::ExplicitlySizedEnum,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericExplicitlySizedEnumSizesView<Storage>::one_byte()
+    const {
+
+  if ( has_one_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::ExplicitlySizedEnum,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::ExplicitlySizedEnum,
+    ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericExplicitlySizedEnumSizesView<Storage>::has_one_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::ExplicitlySizedEnum,
+    ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+ GenericExplicitlySizedEnumSizesView<Storage>::two_byte()
+    const {
+
+  if ( has_two_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::ExplicitlySizedEnum,
+    ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::ExplicitlySizedEnum,
+    ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 16>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericExplicitlySizedEnumSizesView<Storage>::has_two_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::EnumView<
+    /**/ ::emboss::test::ExplicitlySizedEnum,
+    ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+ GenericExplicitlySizedEnumSizesView<Storage>::three_byte()
+    const {
+
+  if ( has_three_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::EnumView<
+    /**/ ::emboss::test::ExplicitlySizedEnum,
+    ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   3>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::EnumView<
+    /**/ ::emboss::test::ExplicitlySizedEnum,
+    ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 3>>, 24>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericExplicitlySizedEnumSizesView<Storage>::has_three_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::ExplicitlySizedEnumSizes::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+ GenericExplicitlySizedEnumSizesView<Storage>::emboss_reserved_anonymous_field_1()
+    const {
+
+  if ( has_emboss_reserved_anonymous_field_1().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::ExplicitlySizedEnumSizes::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   6>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::ExplicitlySizedEnumSizes::GenericEmbossReservedAnonymousField1View<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericExplicitlySizedEnumSizesView<Storage>::has_emboss_reserved_anonymous_field_1() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericExplicitlySizedEnumSizesView<Storage>::has_three_and_a_half_byte() const {
+  return ::emboss::support::And</**/bool, bool, bool, bool>(::emboss::support::Maybe</**/bool>(true), ::emboss::support::Maybe</**/bool>(true));
+}
+
+
+namespace ExplicitlySizedEnumSizes {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)).ValueOrDefault();
+}
+}  // namespace ExplicitlySizedEnumSizes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericExplicitlySizedEnumSizesView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return ExplicitlySizedEnumSizes::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericExplicitlySizedEnumSizesView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return ExplicitlySizedEnumSizes::IntrinsicSizeInBytes();
+}
+
+namespace ExplicitlySizedEnumSizes {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)).ValueOrDefault();
+}
+}  // namespace ExplicitlySizedEnumSizes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericExplicitlySizedEnumSizesView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return ExplicitlySizedEnumSizes::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericExplicitlySizedEnumSizesView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return ExplicitlySizedEnumSizes::MaxSizeInBytes();
+}
+
+namespace ExplicitlySizedEnumSizes {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)).ValueOrDefault();
+}
+}  // namespace ExplicitlySizedEnumSizes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericExplicitlySizedEnumSizesView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return ExplicitlySizedEnumSizes::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericExplicitlySizedEnumSizesView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return ExplicitlySizedEnumSizes::MinSizeInBytes();
+}
+namespace ArraySizes {
+
+}  // namespace ArraySizes
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 1,
+    8 >
+
+ GenericArraySizesView<Storage>::one_byte()
+    const {
+
+  if ( has_one_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 1,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>::template OffsetStorageType</**/1, 0>>, 8>>
+
+, typename Storage::template OffsetStorageType</**/0, 0>, 1,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericArraySizesView<Storage>::has_one_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>::template OffsetStorageType</**/2, 0>>, 16>>
+
+, typename Storage::template OffsetStorageType</**/0, 2>, 2,
+    8 >
+
+ GenericArraySizesView<Storage>::two_byte()
+    const {
+
+  if ( has_two_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>::template OffsetStorageType</**/2, 0>>, 16>>
+
+, typename Storage::template OffsetStorageType</**/0, 2>, 2,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>::template OffsetStorageType</**/2, 0>>, 16>>
+
+, typename Storage::template OffsetStorageType</**/0, 2>, 2,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericArraySizesView<Storage>::has_two_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>::template OffsetStorageType</**/3, 0>>, 24>>
+
+, typename Storage::template OffsetStorageType</**/0, 6>, 3,
+    8 >
+
+ GenericArraySizesView<Storage>::three_byte()
+    const {
+
+  if ( has_three_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(6LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>::template OffsetStorageType</**/3, 0>>, 24>>
+
+, typename Storage::template OffsetStorageType</**/0, 6>, 3,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   6>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<24, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 6>::template OffsetStorageType</**/3, 0>>, 24>>
+
+, typename Storage::template OffsetStorageType</**/0, 6>, 3,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericArraySizesView<Storage>::has_three_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 12>::template OffsetStorageType</**/4, 0>>, 32>>
+
+, typename Storage::template OffsetStorageType</**/0, 12>, 4,
+    8 >
+
+ GenericArraySizesView<Storage>::four_byte()
+    const {
+
+  if ( has_four_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(12LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 12>::template OffsetStorageType</**/4, 0>>, 32>>
+
+, typename Storage::template OffsetStorageType</**/0, 12>, 4,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   12>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 12>::template OffsetStorageType</**/4, 0>>, 32>>
+
+, typename Storage::template OffsetStorageType</**/0, 12>, 4,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericArraySizesView<Storage>::has_four_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 20>::template OffsetStorageType</**/5, 0>>, 40>>
+
+, typename Storage::template OffsetStorageType</**/0, 20>, 5,
+    8 >
+
+ GenericArraySizesView<Storage>::five_byte()
+    const {
+
+  if ( has_five_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(20LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 20>::template OffsetStorageType</**/5, 0>>, 40>>
+
+, typename Storage::template OffsetStorageType</**/0, 20>, 5,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   20>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<40, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 20>::template OffsetStorageType</**/5, 0>>, 40>>
+
+, typename Storage::template OffsetStorageType</**/0, 20>, 5,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericArraySizesView<Storage>::has_five_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 30>::template OffsetStorageType</**/6, 0>>, 48>>
+
+, typename Storage::template OffsetStorageType</**/0, 30>, 6,
+    8 >
+
+ GenericArraySizesView<Storage>::six_byte()
+    const {
+
+  if ( has_six_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(12LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(30LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 30>::template OffsetStorageType</**/6, 0>>, 48>>
+
+, typename Storage::template OffsetStorageType</**/0, 30>, 6,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   30>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<48, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 30>::template OffsetStorageType</**/6, 0>>, 48>>
+
+, typename Storage::template OffsetStorageType</**/0, 30>, 6,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericArraySizesView<Storage>::has_six_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 42>::template OffsetStorageType</**/7, 0>>, 56>>
+
+, typename Storage::template OffsetStorageType</**/0, 42>, 7,
+    8 >
+
+ GenericArraySizesView<Storage>::seven_byte()
+    const {
+
+  if ( has_seven_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(14LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(42LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 42>::template OffsetStorageType</**/7, 0>>, 56>>
+
+, typename Storage::template OffsetStorageType</**/0, 42>, 7,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   42>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<56, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 42>::template OffsetStorageType</**/7, 0>>, 56>>
+
+, typename Storage::template OffsetStorageType</**/0, 42>, 7,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericArraySizesView<Storage>::has_seven_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 56>::template OffsetStorageType</**/8, 0>>, 64>>
+
+, typename Storage::template OffsetStorageType</**/0, 56>, 8,
+    8 >
+
+ GenericArraySizesView<Storage>::eight_byte()
+    const {
+
+  if ( has_eight_byte().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(16LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(56LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 56>::template OffsetStorageType</**/8, 0>>, 64>>
+
+, typename Storage::template OffsetStorageType</**/0, 56>, 8,
+    8 >
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   56>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::support::GenericArrayView<
+    typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<64, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 56>::template OffsetStorageType</**/8, 0>>, 64>>
+
+, typename Storage::template OffsetStorageType</**/0, 56>, 8,
+    8 >
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericArraySizesView<Storage>::has_eight_byte() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace ArraySizes {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(72LL)).ValueOrDefault();
+}
+}  // namespace ArraySizes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericArraySizesView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return ArraySizes::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericArraySizesView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return ArraySizes::IntrinsicSizeInBytes();
+}
+
+namespace ArraySizes {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(72LL)).ValueOrDefault();
+}
+}  // namespace ArraySizes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericArraySizesView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return ArraySizes::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericArraySizesView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return ArraySizes::MaxSizeInBytes();
+}
+
+namespace ArraySizes {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(72LL)).ValueOrDefault();
+}
+}  // namespace ArraySizes
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericArraySizesView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return ArraySizes::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericArraySizesView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return ArraySizes::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_UINT_SIZES_EMB_H_
+
diff --git a/testdata/golden_cpp/virtual_field.emb.h b/testdata/golden_cpp/virtual_field.emb.h
new file mode 100644
index 0000000..140020a
--- /dev/null
+++ b/testdata/golden_cpp/virtual_field.emb.h
@@ -0,0 +1,15819 @@
+/**
+ * Generated by the Emboss compiler.  DO NOT EDIT!
+ */
+#ifndef TESTDATA_VIRTUAL_FIELD_EMB_H_
+#define TESTDATA_VIRTUAL_FIELD_EMB_H_
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+#include "runtime/cpp/emboss_cpp_util.h"
+
+#include "runtime/cpp/emboss_prelude.h"
+
+#include "runtime/cpp/emboss_enum_view.h"
+
+#include "runtime/cpp/emboss_text_util.h"
+
+
+
+/* NOLINTBEGIN */
+namespace emboss {
+namespace test {
+namespace StructureWithConstants {
+
+}  // namespace StructureWithConstants
+
+
+template <class Storage>
+class GenericStructureWithConstantsView;
+
+namespace StructureWithComputedValues {
+
+}  // namespace StructureWithComputedValues
+
+
+template <class Storage>
+class GenericStructureWithComputedValuesView;
+
+namespace StructureWithConditionalValue {
+
+}  // namespace StructureWithConditionalValue
+
+
+template <class Storage>
+class GenericStructureWithConditionalValueView;
+
+namespace StructureWithValueInCondition {
+
+}  // namespace StructureWithValueInCondition
+
+
+template <class Storage>
+class GenericStructureWithValueInConditionView;
+
+namespace StructureWithValuesInLocation {
+
+}  // namespace StructureWithValuesInLocation
+
+
+template <class Storage>
+class GenericStructureWithValuesInLocationView;
+
+namespace StructureWithBoolValue {
+
+}  // namespace StructureWithBoolValue
+
+
+template <class Storage>
+class GenericStructureWithBoolValueView;
+
+namespace StructureWithEnumValue {
+enum class Category : ::std::uint64_t;
+
+
+}  // namespace StructureWithEnumValue
+
+
+template <class Storage>
+class GenericStructureWithEnumValueView;
+
+namespace StructureWithBitsWithValue {
+
+}  // namespace StructureWithBitsWithValue
+
+
+template <class Storage>
+class GenericStructureWithBitsWithValueView;
+
+namespace BitsWithValue {
+
+}  // namespace BitsWithValue
+
+
+template <class Storage>
+class GenericBitsWithValueView;
+
+namespace StructureUsingForeignConstants {
+
+}  // namespace StructureUsingForeignConstants
+
+
+template <class Storage>
+class GenericStructureUsingForeignConstantsView;
+
+namespace SubfieldOfAlias {
+namespace Header {
+
+}  // namespace Header
+
+
+template <class Storage>
+class GenericHeaderView;
+
+
+}  // namespace SubfieldOfAlias
+
+
+template <class Storage>
+class GenericSubfieldOfAliasView;
+
+namespace RestrictedAlias {
+
+}  // namespace RestrictedAlias
+
+
+template <class Storage>
+class GenericRestrictedAliasView;
+
+namespace HasField {
+namespace X {
+
+}  // namespace X
+
+
+template <class Storage>
+class GenericXView;
+
+
+}  // namespace HasField
+
+
+template <class Storage>
+class GenericHasFieldView;
+
+namespace VirtualUnconditionallyUsesConditional {
+
+}  // namespace VirtualUnconditionallyUsesConditional
+
+
+template <class Storage>
+class GenericVirtualUnconditionallyUsesConditionalView;
+
+namespace UsesSize {
+namespace R {
+
+}  // namespace R
+
+
+template <class Storage>
+class GenericRView;
+
+
+}  // namespace UsesSize
+
+
+template <class Storage>
+class GenericUsesSizeView;
+
+namespace UsesExternalSize {
+
+}  // namespace UsesExternalSize
+
+
+template <class Storage>
+class GenericUsesExternalSizeView;
+
+namespace ImplicitWriteBack {
+
+}  // namespace ImplicitWriteBack
+
+
+template <class Storage>
+class GenericImplicitWriteBackView;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+namespace StructureWithConstants {
+
+}  // namespace StructureWithConstants
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructureWithConstantsView;
+
+template <class Storage>
+class GenericStructureWithConstantsView final {
+ public:
+  GenericStructureWithConstantsView() : backing_() {}
+  explicit GenericStructureWithConstantsView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructureWithConstantsView(
+      const GenericStructureWithConstantsView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericStructureWithConstantsView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericStructureWithConstantsView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericStructureWithConstantsView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructureWithConstantsView<Storage> &operator=(
+      const GenericStructureWithConstantsView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_ten().Known()) return false;
+    if (has_ten().ValueOrDefault() && !ten().Ok()) return false;
+
+
+    if (!has_twenty().Known()) return false;
+    if (has_twenty().ValueOrDefault() && !twenty().Ok()) return false;
+
+
+    if (!has_four_billion().Known()) return false;
+    if (has_four_billion().ValueOrDefault() && !four_billion().Ok()) return false;
+
+
+    if (!has_ten_billion().Known()) return false;
+    if (has_ten_billion().ValueOrDefault() && !ten_billion().Ok()) return false;
+
+
+    if (!has_minus_ten_billion().Known()) return false;
+    if (has_minus_ten_billion().ValueOrDefault() && !minus_ten_billion().Ok()) return false;
+
+
+    if (!has_value().Known()) return false;
+    if (has_value().ValueOrDefault() && !value().Ok()) return false;
+
+
+    if (!has_alias_of_value().Known()) return false;
+    if (has_alias_of_value().ValueOrDefault() && !alias_of_value().Ok()) return false;
+
+
+    if (!has_alias_of_alias_of_value().Known()) return false;
+    if (has_alias_of_alias_of_value().ValueOrDefault() && !alias_of_alias_of_value().Ok()) return false;
+
+
+    if (!has_alias_of_ten().Known()) return false;
+    if (has_alias_of_ten().ValueOrDefault() && !alias_of_ten().Ok()) return false;
+
+
+    if (!has_alias_of_alias_of_ten().Known()) return false;
+    if (has_alias_of_alias_of_ten().ValueOrDefault() && !alias_of_alias_of_ten().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericStructureWithConstantsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_value().Known()) return false;
+    if (!emboss_reserved_local_other.has_value().Known()) return false;
+
+    if (emboss_reserved_local_other.has_value().ValueOrDefault() &&
+        !has_value().ValueOrDefault())
+      return false;
+    if (has_value().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_value().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_value().ValueOrDefault() &&
+        has_value().ValueOrDefault() &&
+        !value().Equals(emboss_reserved_local_other.value()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericStructureWithConstantsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_value().ValueOr(false) &&
+        !has_value().ValueOr(false))
+      return false;
+    if (has_value().ValueOr(false) &&
+        !emboss_reserved_local_other.has_value().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_value().ValueOr(false) &&
+        has_value().ValueOr(false) &&
+        !value().UncheckedEquals(emboss_reserved_local_other.value()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericStructureWithConstantsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericStructureWithConstantsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericStructureWithConstantsView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "value") {
+        if (!value().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "alias_of_value") {
+        if (!alias_of_value().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "alias_of_alias_of_value") {
+        if (!alias_of_alias_of_value().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_ten().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          ten().IsAggregate() || ten().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# ten: ");
+        ten().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# ten: UNREADABLE\n");
+      }
+    }
+
+    if (has_twenty().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          twenty().IsAggregate() || twenty().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# twenty: ");
+        twenty().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# twenty: UNREADABLE\n");
+      }
+    }
+
+    if (has_four_billion().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          four_billion().IsAggregate() || four_billion().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# four_billion: ");
+        four_billion().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# four_billion: UNREADABLE\n");
+      }
+    }
+
+    if (has_ten_billion().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          ten_billion().IsAggregate() || ten_billion().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# ten_billion: ");
+        ten_billion().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# ten_billion: UNREADABLE\n");
+      }
+    }
+
+    if (has_minus_ten_billion().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          minus_ten_billion().IsAggregate() || minus_ten_billion().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# minus_ten_billion: ");
+        minus_ten_billion().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# minus_ten_billion: UNREADABLE\n");
+      }
+    }
+
+    if (has_value().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          value().IsAggregate() || value().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("value: ");
+        value().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !value().IsAggregate() && !value().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# value: UNREADABLE\n");
+      }
+    }
+
+    if (has_alias_of_value().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          alias_of_value().IsAggregate() || alias_of_value().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("alias_of_value: ");
+        alias_of_value().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !alias_of_value().IsAggregate() && !alias_of_value().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# alias_of_value: UNREADABLE\n");
+      }
+    }
+
+    if (has_alias_of_alias_of_value().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          alias_of_alias_of_value().IsAggregate() || alias_of_alias_of_value().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("alias_of_alias_of_value: ");
+        alias_of_alias_of_value().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !alias_of_alias_of_value().IsAggregate() && !alias_of_alias_of_value().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# alias_of_alias_of_value: UNREADABLE\n");
+      }
+    }
+
+    if (has_alias_of_ten().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          alias_of_ten().IsAggregate() || alias_of_ten().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# alias_of_ten: ");
+        alias_of_ten().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# alias_of_ten: UNREADABLE\n");
+      }
+    }
+
+    if (has_alias_of_alias_of_ten().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          alias_of_alias_of_ten().IsAggregate() || alias_of_alias_of_ten().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# alias_of_alias_of_ten: ");
+        alias_of_alias_of_ten().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# alias_of_alias_of_ten: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  class EmbossReservedVirtualTenView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedVirtualTenView() {}
+    EmbossReservedVirtualTenView(const EmbossReservedVirtualTenView &) = default;
+    EmbossReservedVirtualTenView(EmbossReservedVirtualTenView &&) = default;
+    EmbossReservedVirtualTenView &operator=(const EmbossReservedVirtualTenView &) =
+        default;
+    EmbossReservedVirtualTenView &operator=(EmbossReservedVirtualTenView &&) =
+        default;
+    ~EmbossReservedVirtualTenView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedVirtualTenView ten() {
+    return EmbossReservedVirtualTenView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_ten() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedVirtualTwentyView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedVirtualTwentyView() {}
+    EmbossReservedVirtualTwentyView(const EmbossReservedVirtualTwentyView &) = default;
+    EmbossReservedVirtualTwentyView(EmbossReservedVirtualTwentyView &&) = default;
+    EmbossReservedVirtualTwentyView &operator=(const EmbossReservedVirtualTwentyView &) =
+        default;
+    EmbossReservedVirtualTwentyView &operator=(EmbossReservedVirtualTwentyView &&) =
+        default;
+    ~EmbossReservedVirtualTwentyView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedVirtualTwentyView twenty() {
+    return EmbossReservedVirtualTwentyView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_twenty() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedVirtualFourBillionView final {
+   public:
+    using ValueType = ::std::uint32_t;
+
+    constexpr EmbossReservedVirtualFourBillionView() {}
+    EmbossReservedVirtualFourBillionView(const EmbossReservedVirtualFourBillionView &) = default;
+    EmbossReservedVirtualFourBillionView(EmbossReservedVirtualFourBillionView &&) = default;
+    EmbossReservedVirtualFourBillionView &operator=(const EmbossReservedVirtualFourBillionView &) =
+        default;
+    EmbossReservedVirtualFourBillionView &operator=(EmbossReservedVirtualFourBillionView &&) =
+        default;
+    ~EmbossReservedVirtualFourBillionView() = default;
+
+    static constexpr ::std::uint32_t Read();
+    static constexpr ::std::uint32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedVirtualFourBillionView four_billion() {
+    return EmbossReservedVirtualFourBillionView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_four_billion() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedVirtualTenBillionView final {
+   public:
+    using ValueType = ::std::int64_t;
+
+    constexpr EmbossReservedVirtualTenBillionView() {}
+    EmbossReservedVirtualTenBillionView(const EmbossReservedVirtualTenBillionView &) = default;
+    EmbossReservedVirtualTenBillionView(EmbossReservedVirtualTenBillionView &&) = default;
+    EmbossReservedVirtualTenBillionView &operator=(const EmbossReservedVirtualTenBillionView &) =
+        default;
+    EmbossReservedVirtualTenBillionView &operator=(EmbossReservedVirtualTenBillionView &&) =
+        default;
+    ~EmbossReservedVirtualTenBillionView() = default;
+
+    static constexpr ::std::int64_t Read();
+    static constexpr ::std::int64_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedVirtualTenBillionView ten_billion() {
+    return EmbossReservedVirtualTenBillionView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_ten_billion() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedVirtualMinusTenBillionView final {
+   public:
+    using ValueType = ::std::int64_t;
+
+    constexpr EmbossReservedVirtualMinusTenBillionView() {}
+    EmbossReservedVirtualMinusTenBillionView(const EmbossReservedVirtualMinusTenBillionView &) = default;
+    EmbossReservedVirtualMinusTenBillionView(EmbossReservedVirtualMinusTenBillionView &&) = default;
+    EmbossReservedVirtualMinusTenBillionView &operator=(const EmbossReservedVirtualMinusTenBillionView &) =
+        default;
+    EmbossReservedVirtualMinusTenBillionView &operator=(EmbossReservedVirtualMinusTenBillionView &&) =
+        default;
+    ~EmbossReservedVirtualMinusTenBillionView() = default;
+
+    static constexpr ::std::int64_t Read();
+    static constexpr ::std::int64_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedVirtualMinusTenBillionView minus_ten_billion() {
+    return EmbossReservedVirtualMinusTenBillionView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_minus_ten_billion() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ value() const;
+  ::emboss::support::Maybe<bool> has_value() const;
+
+ public:
+  auto alias_of_value() const -> decltype(this->value()) {
+   return has_alias_of_value().ValueOrDefault() ? value()
+                                          : decltype(this->value())();
+  }
+  ::emboss::support::Maybe<bool> has_alias_of_value() const;
+
+ public:
+  auto alias_of_alias_of_value() const -> decltype(this->alias_of_value()) {
+   return has_alias_of_alias_of_value().ValueOrDefault() ? alias_of_value()
+                                          : decltype(this->alias_of_value())();
+  }
+  ::emboss::support::Maybe<bool> has_alias_of_alias_of_value() const;
+
+ public:
+  class EmbossReservedVirtualAliasOfTenView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedVirtualAliasOfTenView() {}
+    EmbossReservedVirtualAliasOfTenView(const EmbossReservedVirtualAliasOfTenView &) = default;
+    EmbossReservedVirtualAliasOfTenView(EmbossReservedVirtualAliasOfTenView &&) = default;
+    EmbossReservedVirtualAliasOfTenView &operator=(const EmbossReservedVirtualAliasOfTenView &) =
+        default;
+    EmbossReservedVirtualAliasOfTenView &operator=(EmbossReservedVirtualAliasOfTenView &&) =
+        default;
+    ~EmbossReservedVirtualAliasOfTenView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedVirtualAliasOfTenView alias_of_ten() {
+    return EmbossReservedVirtualAliasOfTenView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_alias_of_ten() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedVirtualAliasOfAliasOfTenView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedVirtualAliasOfAliasOfTenView() {}
+    EmbossReservedVirtualAliasOfAliasOfTenView(const EmbossReservedVirtualAliasOfAliasOfTenView &) = default;
+    EmbossReservedVirtualAliasOfAliasOfTenView(EmbossReservedVirtualAliasOfAliasOfTenView &&) = default;
+    EmbossReservedVirtualAliasOfAliasOfTenView &operator=(const EmbossReservedVirtualAliasOfAliasOfTenView &) =
+        default;
+    EmbossReservedVirtualAliasOfAliasOfTenView &operator=(EmbossReservedVirtualAliasOfAliasOfTenView &&) =
+        default;
+    ~EmbossReservedVirtualAliasOfAliasOfTenView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedVirtualAliasOfAliasOfTenView alias_of_alias_of_ten() {
+    return EmbossReservedVirtualAliasOfAliasOfTenView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_alias_of_alias_of_ten() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericStructureWithConstantsView;
+};
+using StructureWithConstantsView =
+    GenericStructureWithConstantsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using StructureWithConstantsWriter =
+    GenericStructureWithConstantsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructureWithConstantsView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericStructureWithConstantsView<
+    GenericStructureWithConstantsView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericStructureWithConstantsView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeStructureWithConstantsView( T &&emboss_reserved_local_arg) {
+  return GenericStructureWithConstantsView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericStructureWithConstantsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeStructureWithConstantsView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericStructureWithConstantsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericStructureWithConstantsView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedStructureWithConstantsView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericStructureWithConstantsView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+
+
+
+
+namespace StructureWithComputedValues {
+
+}  // namespace StructureWithComputedValues
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructureWithComputedValuesView;
+
+template <class Storage>
+class GenericStructureWithComputedValuesView final {
+ public:
+  GenericStructureWithComputedValuesView() : backing_() {}
+  explicit GenericStructureWithComputedValuesView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructureWithComputedValuesView(
+      const GenericStructureWithComputedValuesView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericStructureWithComputedValuesView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericStructureWithComputedValuesView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericStructureWithComputedValuesView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructureWithComputedValuesView<Storage> &operator=(
+      const GenericStructureWithComputedValuesView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_value().Known()) return false;
+    if (has_value().ValueOrDefault() && !value().Ok()) return false;
+
+
+    if (!has_doubled().Known()) return false;
+    if (has_doubled().ValueOrDefault() && !doubled().Ok()) return false;
+
+
+    if (!has_plus_ten().Known()) return false;
+    if (has_plus_ten().ValueOrDefault() && !plus_ten().Ok()) return false;
+
+
+    if (!has_value2().Known()) return false;
+    if (has_value2().ValueOrDefault() && !value2().Ok()) return false;
+
+
+    if (!has_signed_doubled().Known()) return false;
+    if (has_signed_doubled().ValueOrDefault() && !signed_doubled().Ok()) return false;
+
+
+    if (!has_signed_plus_ten().Known()) return false;
+    if (has_signed_plus_ten().ValueOrDefault() && !signed_plus_ten().Ok()) return false;
+
+
+    if (!has_product().Known()) return false;
+    if (has_product().ValueOrDefault() && !product().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericStructureWithComputedValuesView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_value().Known()) return false;
+    if (!emboss_reserved_local_other.has_value().Known()) return false;
+
+    if (emboss_reserved_local_other.has_value().ValueOrDefault() &&
+        !has_value().ValueOrDefault())
+      return false;
+    if (has_value().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_value().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_value().ValueOrDefault() &&
+        has_value().ValueOrDefault() &&
+        !value().Equals(emboss_reserved_local_other.value()))
+      return false;
+
+
+
+    if (!has_value2().Known()) return false;
+    if (!emboss_reserved_local_other.has_value2().Known()) return false;
+
+    if (emboss_reserved_local_other.has_value2().ValueOrDefault() &&
+        !has_value2().ValueOrDefault())
+      return false;
+    if (has_value2().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_value2().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_value2().ValueOrDefault() &&
+        has_value2().ValueOrDefault() &&
+        !value2().Equals(emboss_reserved_local_other.value2()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericStructureWithComputedValuesView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_value().ValueOr(false) &&
+        !has_value().ValueOr(false))
+      return false;
+    if (has_value().ValueOr(false) &&
+        !emboss_reserved_local_other.has_value().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_value().ValueOr(false) &&
+        has_value().ValueOr(false) &&
+        !value().UncheckedEquals(emboss_reserved_local_other.value()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_value2().ValueOr(false) &&
+        !has_value2().ValueOr(false))
+      return false;
+    if (has_value2().ValueOr(false) &&
+        !emboss_reserved_local_other.has_value2().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_value2().ValueOr(false) &&
+        has_value2().ValueOr(false) &&
+        !value2().UncheckedEquals(emboss_reserved_local_other.value2()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericStructureWithComputedValuesView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericStructureWithComputedValuesView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericStructureWithComputedValuesView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "value") {
+        if (!value().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "plus_ten") {
+        if (!plus_ten().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "value2") {
+        if (!value2().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "signed_plus_ten") {
+        if (!signed_plus_ten().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_value().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          value().IsAggregate() || value().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("value: ");
+        value().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !value().IsAggregate() && !value().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# value: UNREADABLE\n");
+      }
+    }
+
+    if (has_doubled().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          doubled().IsAggregate() || doubled().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# doubled: ");
+        doubled().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# doubled: UNREADABLE\n");
+      }
+    }
+
+    if (has_plus_ten().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          plus_ten().IsAggregate() || plus_ten().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("plus_ten: ");
+        plus_ten().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !plus_ten().IsAggregate() && !plus_ten().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# plus_ten: UNREADABLE\n");
+      }
+    }
+
+    if (has_value2().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          value2().IsAggregate() || value2().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("value2: ");
+        value2().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !value2().IsAggregate() && !value2().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# value2: UNREADABLE\n");
+      }
+    }
+
+    if (has_signed_doubled().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          signed_doubled().IsAggregate() || signed_doubled().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# signed_doubled: ");
+        signed_doubled().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# signed_doubled: UNREADABLE\n");
+      }
+    }
+
+    if (has_signed_plus_ten().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          signed_plus_ten().IsAggregate() || signed_plus_ten().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("signed_plus_ten: ");
+        signed_plus_ten().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !signed_plus_ten().IsAggregate() && !signed_plus_ten().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# signed_plus_ten: UNREADABLE\n");
+      }
+    }
+
+    if (has_product().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          product().IsAggregate() || product().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# product: ");
+        product().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# product: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ value() const;
+  ::emboss::support::Maybe<bool> has_value() const;
+
+ public:
+  class EmbossReservedVirtualDoubledView final {
+   public:
+    using ValueType = ::std::int64_t;
+
+    explicit EmbossReservedVirtualDoubledView(
+        const GenericStructureWithComputedValuesView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualDoubledView() = delete;
+    EmbossReservedVirtualDoubledView(const EmbossReservedVirtualDoubledView &) = default;
+    EmbossReservedVirtualDoubledView(EmbossReservedVirtualDoubledView &&) = default;
+    EmbossReservedVirtualDoubledView &operator=(const EmbossReservedVirtualDoubledView &) =
+        default;
+    EmbossReservedVirtualDoubledView &operator=(EmbossReservedVirtualDoubledView &&) =
+        default;
+    ~EmbossReservedVirtualDoubledView() = default;
+
+    ::std::int64_t Read() const {
+      EMBOSS_CHECK(view_.has_doubled().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int64_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int64_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.value();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::uint32_t>(static_cast</**/::std::uint32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::uint32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Product</**/::std::int64_t, ::std::int64_t, ::std::uint32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)));
+
+      return emboss_reserved_local_subexpr_3;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int64_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericStructureWithComputedValuesView view_;
+  };
+  EmbossReservedVirtualDoubledView doubled() const;
+  ::emboss::support::Maybe<bool> has_doubled() const;
+
+ public:
+  class EmbossReservedVirtualPlusTenView final {
+   public:
+    using ValueType = ::std::int64_t;
+
+    explicit EmbossReservedVirtualPlusTenView(
+        const GenericStructureWithComputedValuesView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualPlusTenView() = delete;
+    EmbossReservedVirtualPlusTenView(const EmbossReservedVirtualPlusTenView &) = default;
+    EmbossReservedVirtualPlusTenView(EmbossReservedVirtualPlusTenView &&) = default;
+    EmbossReservedVirtualPlusTenView &operator=(const EmbossReservedVirtualPlusTenView &) =
+        default;
+    EmbossReservedVirtualPlusTenView &operator=(EmbossReservedVirtualPlusTenView &&) =
+        default;
+    ~EmbossReservedVirtualPlusTenView() = default;
+
+    ::std::int64_t Read() const {
+      EMBOSS_CHECK(view_.has_plus_ten().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int64_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+    bool TryToWrite(::std::int64_t emboss_reserved_local_value) {
+      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Difference</**/::std::int64_t, ::std::uint32_t, ::std::int64_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)));
+      if (!CouldWriteValue(emboss_reserved_local_value)) return false;
+      return view_.value().TryToWrite(
+          emboss_reserved_local_maybe_new_value.ValueOrDefault());
+    }
+    void Write(::std::int64_t emboss_reserved_local_value) {
+      const bool result = TryToWrite(emboss_reserved_local_value);
+      (void)result;
+      EMBOSS_CHECK(result);
+    }
+    void UncheckedWrite(::std::int64_t emboss_reserved_local_value) {
+      view_.value().UncheckedWrite((::emboss::support::Difference</**/::std::int64_t, ::std::uint32_t, ::std::int64_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)))).ValueOrDefault());
+    }
+    bool CouldWriteValue(::std::int64_t emboss_reserved_local_value) {
+      if (!ValueIsOk(emboss_reserved_local_value)) return false;
+      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Difference</**/::std::int64_t, ::std::uint32_t, ::std::int64_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)));
+      if (!emboss_reserved_local_maybe_new_value.Known()) return false;
+      return view_.value().CouldWriteValue(
+          emboss_reserved_local_maybe_new_value.ValueOrDefault());
+    }
+    template <class Stream>
+    bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) {
+      return ::emboss::support::ReadIntegerFromTextStream(
+          this, emboss_reserved_local_stream);
+    }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int64_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.value();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::uint32_t>(static_cast</**/::std::uint32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::uint32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int64_t, ::std::int64_t, ::std::uint32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)));
+
+      return emboss_reserved_local_subexpr_3;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int64_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericStructureWithComputedValuesView view_;
+  };
+  EmbossReservedVirtualPlusTenView plus_ten() const;
+  ::emboss::support::Maybe<bool> has_plus_ten() const;
+
+ public:
+  typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+ value2() const;
+  ::emboss::support::Maybe<bool> has_value2() const;
+
+ public:
+  class EmbossReservedVirtualSignedDoubledView final {
+   public:
+    using ValueType = ::std::int64_t;
+
+    explicit EmbossReservedVirtualSignedDoubledView(
+        const GenericStructureWithComputedValuesView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualSignedDoubledView() = delete;
+    EmbossReservedVirtualSignedDoubledView(const EmbossReservedVirtualSignedDoubledView &) = default;
+    EmbossReservedVirtualSignedDoubledView(EmbossReservedVirtualSignedDoubledView &&) = default;
+    EmbossReservedVirtualSignedDoubledView &operator=(const EmbossReservedVirtualSignedDoubledView &) =
+        default;
+    EmbossReservedVirtualSignedDoubledView &operator=(EmbossReservedVirtualSignedDoubledView &&) =
+        default;
+    ~EmbossReservedVirtualSignedDoubledView() = default;
+
+    ::std::int64_t Read() const {
+      EMBOSS_CHECK(view_.has_signed_doubled().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int64_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int64_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.value2();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Product</**/::std::int64_t, ::std::int64_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)));
+
+      return emboss_reserved_local_subexpr_3;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int64_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericStructureWithComputedValuesView view_;
+  };
+  EmbossReservedVirtualSignedDoubledView signed_doubled() const;
+  ::emboss::support::Maybe<bool> has_signed_doubled() const;
+
+ public:
+  class EmbossReservedVirtualSignedPlusTenView final {
+   public:
+    using ValueType = ::std::int64_t;
+
+    explicit EmbossReservedVirtualSignedPlusTenView(
+        const GenericStructureWithComputedValuesView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualSignedPlusTenView() = delete;
+    EmbossReservedVirtualSignedPlusTenView(const EmbossReservedVirtualSignedPlusTenView &) = default;
+    EmbossReservedVirtualSignedPlusTenView(EmbossReservedVirtualSignedPlusTenView &&) = default;
+    EmbossReservedVirtualSignedPlusTenView &operator=(const EmbossReservedVirtualSignedPlusTenView &) =
+        default;
+    EmbossReservedVirtualSignedPlusTenView &operator=(EmbossReservedVirtualSignedPlusTenView &&) =
+        default;
+    ~EmbossReservedVirtualSignedPlusTenView() = default;
+
+    ::std::int64_t Read() const {
+      EMBOSS_CHECK(view_.has_signed_plus_ten().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int64_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+    bool TryToWrite(::std::int64_t emboss_reserved_local_value) {
+      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Difference</**/::std::int64_t, ::std::int32_t, ::std::int64_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)));
+      if (!CouldWriteValue(emboss_reserved_local_value)) return false;
+      return view_.value2().TryToWrite(
+          emboss_reserved_local_maybe_new_value.ValueOrDefault());
+    }
+    void Write(::std::int64_t emboss_reserved_local_value) {
+      const bool result = TryToWrite(emboss_reserved_local_value);
+      (void)result;
+      EMBOSS_CHECK(result);
+    }
+    void UncheckedWrite(::std::int64_t emboss_reserved_local_value) {
+      view_.value2().UncheckedWrite((::emboss::support::Difference</**/::std::int64_t, ::std::int32_t, ::std::int64_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)))).ValueOrDefault());
+    }
+    bool CouldWriteValue(::std::int64_t emboss_reserved_local_value) {
+      if (!ValueIsOk(emboss_reserved_local_value)) return false;
+      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Difference</**/::std::int64_t, ::std::int32_t, ::std::int64_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)));
+      if (!emboss_reserved_local_maybe_new_value.Known()) return false;
+      return view_.value2().CouldWriteValue(
+          emboss_reserved_local_maybe_new_value.ValueOrDefault());
+    }
+    template <class Stream>
+    bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) {
+      return ::emboss::support::ReadIntegerFromTextStream(
+          this, emboss_reserved_local_stream);
+    }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int64_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.value2();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int64_t, ::std::int64_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)));
+
+      return emboss_reserved_local_subexpr_3;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int64_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericStructureWithComputedValuesView view_;
+  };
+  EmbossReservedVirtualSignedPlusTenView signed_plus_ten() const;
+  ::emboss::support::Maybe<bool> has_signed_plus_ten() const;
+
+ public:
+  class EmbossReservedVirtualProductView final {
+   public:
+    using ValueType = ::std::int64_t;
+
+    explicit EmbossReservedVirtualProductView(
+        const GenericStructureWithComputedValuesView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualProductView() = delete;
+    EmbossReservedVirtualProductView(const EmbossReservedVirtualProductView &) = default;
+    EmbossReservedVirtualProductView(EmbossReservedVirtualProductView &&) = default;
+    EmbossReservedVirtualProductView &operator=(const EmbossReservedVirtualProductView &) =
+        default;
+    EmbossReservedVirtualProductView &operator=(EmbossReservedVirtualProductView &&) =
+        default;
+    ~EmbossReservedVirtualProductView() = default;
+
+    ::std::int64_t Read() const {
+      EMBOSS_CHECK(view_.has_product().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int64_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int64_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.value();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::uint32_t>(static_cast</**/::std::uint32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::uint32_t>());
+      const auto emboss_reserved_local_subexpr_3 = view_.value2();
+      const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Product</**/::std::int64_t, ::std::int64_t, ::std::uint32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_4);
+
+      return emboss_reserved_local_subexpr_5;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int64_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericStructureWithComputedValuesView view_;
+  };
+  EmbossReservedVirtualProductView product() const;
+  ::emboss::support::Maybe<bool> has_product() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericStructureWithComputedValuesView;
+};
+using StructureWithComputedValuesView =
+    GenericStructureWithComputedValuesView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using StructureWithComputedValuesWriter =
+    GenericStructureWithComputedValuesView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructureWithComputedValuesView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericStructureWithComputedValuesView<
+    GenericStructureWithComputedValuesView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericStructureWithComputedValuesView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeStructureWithComputedValuesView( T &&emboss_reserved_local_arg) {
+  return GenericStructureWithComputedValuesView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericStructureWithComputedValuesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeStructureWithComputedValuesView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericStructureWithComputedValuesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericStructureWithComputedValuesView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedStructureWithComputedValuesView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericStructureWithComputedValuesView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace StructureWithConditionalValue {
+
+}  // namespace StructureWithConditionalValue
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructureWithConditionalValueView;
+
+template <class Storage>
+class GenericStructureWithConditionalValueView final {
+ public:
+  GenericStructureWithConditionalValueView() : backing_() {}
+  explicit GenericStructureWithConditionalValueView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructureWithConditionalValueView(
+      const GenericStructureWithConditionalValueView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericStructureWithConditionalValueView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericStructureWithConditionalValueView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericStructureWithConditionalValueView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructureWithConditionalValueView<Storage> &operator=(
+      const GenericStructureWithConditionalValueView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_two_x().Known()) return false;
+    if (has_two_x().ValueOrDefault() && !two_x().Ok()) return false;
+
+
+    if (!has_x_plus_one().Known()) return false;
+    if (has_x_plus_one().ValueOrDefault() && !x_plus_one().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericStructureWithConditionalValueView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericStructureWithConditionalValueView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericStructureWithConditionalValueView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericStructureWithConditionalValueView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericStructureWithConditionalValueView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "x_plus_one") {
+        if (!x_plus_one().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_two_x().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          two_x().IsAggregate() || two_x().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# two_x: ");
+        two_x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# two_x: UNREADABLE\n");
+      }
+    }
+
+    if (has_x_plus_one().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x_plus_one().IsAggregate() || x_plus_one().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x_plus_one: ");
+        x_plus_one().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x_plus_one().IsAggregate() && !x_plus_one().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x_plus_one: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  class EmbossReservedVirtualTwoXView final {
+   public:
+    using ValueType = ::std::int64_t;
+
+    explicit EmbossReservedVirtualTwoXView(
+        const GenericStructureWithConditionalValueView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualTwoXView() = delete;
+    EmbossReservedVirtualTwoXView(const EmbossReservedVirtualTwoXView &) = default;
+    EmbossReservedVirtualTwoXView(EmbossReservedVirtualTwoXView &&) = default;
+    EmbossReservedVirtualTwoXView &operator=(const EmbossReservedVirtualTwoXView &) =
+        default;
+    EmbossReservedVirtualTwoXView &operator=(EmbossReservedVirtualTwoXView &&) =
+        default;
+    ~EmbossReservedVirtualTwoXView() = default;
+
+    ::std::int64_t Read() const {
+      EMBOSS_CHECK(view_.has_two_x().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int64_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int64_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::uint32_t>(static_cast</**/::std::uint32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::uint32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Product</**/::std::int64_t, ::std::int64_t, ::std::uint32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)));
+
+      return emboss_reserved_local_subexpr_3;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int64_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericStructureWithConditionalValueView view_;
+  };
+  EmbossReservedVirtualTwoXView two_x() const;
+  ::emboss::support::Maybe<bool> has_two_x() const;
+
+ public:
+  class EmbossReservedVirtualXPlusOneView final {
+   public:
+    using ValueType = ::std::int64_t;
+
+    explicit EmbossReservedVirtualXPlusOneView(
+        const GenericStructureWithConditionalValueView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualXPlusOneView() = delete;
+    EmbossReservedVirtualXPlusOneView(const EmbossReservedVirtualXPlusOneView &) = default;
+    EmbossReservedVirtualXPlusOneView(EmbossReservedVirtualXPlusOneView &&) = default;
+    EmbossReservedVirtualXPlusOneView &operator=(const EmbossReservedVirtualXPlusOneView &) =
+        default;
+    EmbossReservedVirtualXPlusOneView &operator=(EmbossReservedVirtualXPlusOneView &&) =
+        default;
+    ~EmbossReservedVirtualXPlusOneView() = default;
+
+    ::std::int64_t Read() const {
+      EMBOSS_CHECK(view_.has_x_plus_one().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int64_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+    bool TryToWrite(::std::int64_t emboss_reserved_local_value) {
+      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Difference</**/::std::int64_t, ::std::uint32_t, ::std::int64_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      if (!CouldWriteValue(emboss_reserved_local_value)) return false;
+      return view_.x().TryToWrite(
+          emboss_reserved_local_maybe_new_value.ValueOrDefault());
+    }
+    void Write(::std::int64_t emboss_reserved_local_value) {
+      const bool result = TryToWrite(emboss_reserved_local_value);
+      (void)result;
+      EMBOSS_CHECK(result);
+    }
+    void UncheckedWrite(::std::int64_t emboss_reserved_local_value) {
+      view_.x().UncheckedWrite((::emboss::support::Difference</**/::std::int64_t, ::std::uint32_t, ::std::int64_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)))).ValueOrDefault());
+    }
+    bool CouldWriteValue(::std::int64_t emboss_reserved_local_value) {
+      if (!ValueIsOk(emboss_reserved_local_value)) return false;
+      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Difference</**/::std::int64_t, ::std::uint32_t, ::std::int64_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+      if (!emboss_reserved_local_maybe_new_value.Known()) return false;
+      return view_.x().CouldWriteValue(
+          emboss_reserved_local_maybe_new_value.ValueOrDefault());
+    }
+    template <class Stream>
+    bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) {
+      return ::emboss::support::ReadIntegerFromTextStream(
+          this, emboss_reserved_local_stream);
+    }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int64_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::uint32_t>(static_cast</**/::std::uint32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::uint32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int64_t, ::std::int64_t, ::std::uint32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+
+      return emboss_reserved_local_subexpr_3;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int64_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericStructureWithConditionalValueView view_;
+  };
+  EmbossReservedVirtualXPlusOneView x_plus_one() const;
+  ::emboss::support::Maybe<bool> has_x_plus_one() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericStructureWithConditionalValueView;
+};
+using StructureWithConditionalValueView =
+    GenericStructureWithConditionalValueView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using StructureWithConditionalValueWriter =
+    GenericStructureWithConditionalValueView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructureWithConditionalValueView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericStructureWithConditionalValueView<
+    GenericStructureWithConditionalValueView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericStructureWithConditionalValueView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeStructureWithConditionalValueView( T &&emboss_reserved_local_arg) {
+  return GenericStructureWithConditionalValueView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericStructureWithConditionalValueView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeStructureWithConditionalValueView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericStructureWithConditionalValueView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericStructureWithConditionalValueView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedStructureWithConditionalValueView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericStructureWithConditionalValueView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace StructureWithValueInCondition {
+
+}  // namespace StructureWithValueInCondition
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructureWithValueInConditionView;
+
+template <class Storage>
+class GenericStructureWithValueInConditionView final {
+ public:
+  GenericStructureWithValueInConditionView() : backing_() {}
+  explicit GenericStructureWithValueInConditionView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructureWithValueInConditionView(
+      const GenericStructureWithValueInConditionView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericStructureWithValueInConditionView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericStructureWithValueInConditionView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericStructureWithValueInConditionView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructureWithValueInConditionView<Storage> &operator=(
+      const GenericStructureWithValueInConditionView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_two_x().Known()) return false;
+    if (has_two_x().ValueOrDefault() && !two_x().Ok()) return false;
+
+
+    if (!has_if_two_x_lt_100().Known()) return false;
+    if (has_if_two_x_lt_100().ValueOrDefault() && !if_two_x_lt_100().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericStructureWithValueInConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_if_two_x_lt_100().Known()) return false;
+    if (!emboss_reserved_local_other.has_if_two_x_lt_100().Known()) return false;
+
+    if (emboss_reserved_local_other.has_if_two_x_lt_100().ValueOrDefault() &&
+        !has_if_two_x_lt_100().ValueOrDefault())
+      return false;
+    if (has_if_two_x_lt_100().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_if_two_x_lt_100().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_if_two_x_lt_100().ValueOrDefault() &&
+        has_if_two_x_lt_100().ValueOrDefault() &&
+        !if_two_x_lt_100().Equals(emboss_reserved_local_other.if_two_x_lt_100()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericStructureWithValueInConditionView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_if_two_x_lt_100().ValueOr(false) &&
+        !has_if_two_x_lt_100().ValueOr(false))
+      return false;
+    if (has_if_two_x_lt_100().ValueOr(false) &&
+        !emboss_reserved_local_other.has_if_two_x_lt_100().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_if_two_x_lt_100().ValueOr(false) &&
+        has_if_two_x_lt_100().ValueOr(false) &&
+        !if_two_x_lt_100().UncheckedEquals(emboss_reserved_local_other.if_two_x_lt_100()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericStructureWithValueInConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericStructureWithValueInConditionView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericStructureWithValueInConditionView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "if_two_x_lt_100") {
+        if (!if_two_x_lt_100().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_two_x().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          two_x().IsAggregate() || two_x().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# two_x: ");
+        two_x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# two_x: UNREADABLE\n");
+      }
+    }
+
+    if (has_if_two_x_lt_100().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          if_two_x_lt_100().IsAggregate() || if_two_x_lt_100().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("if_two_x_lt_100: ");
+        if_two_x_lt_100().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !if_two_x_lt_100().IsAggregate() && !if_two_x_lt_100().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# if_two_x_lt_100: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  class EmbossReservedVirtualTwoXView final {
+   public:
+    using ValueType = ::std::int64_t;
+
+    explicit EmbossReservedVirtualTwoXView(
+        const GenericStructureWithValueInConditionView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualTwoXView() = delete;
+    EmbossReservedVirtualTwoXView(const EmbossReservedVirtualTwoXView &) = default;
+    EmbossReservedVirtualTwoXView(EmbossReservedVirtualTwoXView &&) = default;
+    EmbossReservedVirtualTwoXView &operator=(const EmbossReservedVirtualTwoXView &) =
+        default;
+    EmbossReservedVirtualTwoXView &operator=(EmbossReservedVirtualTwoXView &&) =
+        default;
+    ~EmbossReservedVirtualTwoXView() = default;
+
+    ::std::int64_t Read() const {
+      EMBOSS_CHECK(view_.has_two_x().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int64_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int64_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::uint32_t>(static_cast</**/::std::uint32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::uint32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Product</**/::std::int64_t, ::std::int64_t, ::std::uint32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)));
+
+      return emboss_reserved_local_subexpr_3;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int64_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericStructureWithValueInConditionView view_;
+  };
+  EmbossReservedVirtualTwoXView two_x() const;
+  ::emboss::support::Maybe<bool> has_two_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+ if_two_x_lt_100() const;
+  ::emboss::support::Maybe<bool> has_if_two_x_lt_100() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericStructureWithValueInConditionView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.two_x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int64_t>(static_cast</**/::std::int64_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int64_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::LessThan</**/::std::int64_t, bool, ::std::int64_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(100LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)), emboss_reserved_local_subexpr_4);
+
+      return emboss_reserved_local_subexpr_5;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericStructureWithValueInConditionView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericStructureWithValueInConditionView;
+};
+using StructureWithValueInConditionView =
+    GenericStructureWithValueInConditionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using StructureWithValueInConditionWriter =
+    GenericStructureWithValueInConditionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructureWithValueInConditionView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericStructureWithValueInConditionView<
+    GenericStructureWithValueInConditionView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericStructureWithValueInConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeStructureWithValueInConditionView( T &&emboss_reserved_local_arg) {
+  return GenericStructureWithValueInConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericStructureWithValueInConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeStructureWithValueInConditionView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericStructureWithValueInConditionView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericStructureWithValueInConditionView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedStructureWithValueInConditionView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericStructureWithValueInConditionView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+
+namespace StructureWithValuesInLocation {
+
+}  // namespace StructureWithValuesInLocation
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructureWithValuesInLocationView;
+
+template <class Storage>
+class GenericStructureWithValuesInLocationView final {
+ public:
+  GenericStructureWithValuesInLocationView() : backing_() {}
+  explicit GenericStructureWithValuesInLocationView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructureWithValuesInLocationView(
+      const GenericStructureWithValuesInLocationView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericStructureWithValuesInLocationView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericStructureWithValuesInLocationView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericStructureWithValuesInLocationView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructureWithValuesInLocationView<Storage> &operator=(
+      const GenericStructureWithValuesInLocationView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_two_x().Known()) return false;
+    if (has_two_x().ValueOrDefault() && !two_x().Ok()) return false;
+
+
+    if (!has_offset_two_x().Known()) return false;
+    if (has_offset_two_x().ValueOrDefault() && !offset_two_x().Ok()) return false;
+
+
+    if (!has_size_two_x().Known()) return false;
+    if (has_size_two_x().ValueOrDefault() && !size_two_x().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericStructureWithValuesInLocationView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_offset_two_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_offset_two_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_offset_two_x().ValueOrDefault() &&
+        !has_offset_two_x().ValueOrDefault())
+      return false;
+    if (has_offset_two_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_offset_two_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_offset_two_x().ValueOrDefault() &&
+        has_offset_two_x().ValueOrDefault() &&
+        !offset_two_x().Equals(emboss_reserved_local_other.offset_two_x()))
+      return false;
+
+
+
+    if (!has_size_two_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_size_two_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_size_two_x().ValueOrDefault() &&
+        !has_size_two_x().ValueOrDefault())
+      return false;
+    if (has_size_two_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_size_two_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_size_two_x().ValueOrDefault() &&
+        has_size_two_x().ValueOrDefault() &&
+        !size_two_x().Equals(emboss_reserved_local_other.size_two_x()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericStructureWithValuesInLocationView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_offset_two_x().ValueOr(false) &&
+        !has_offset_two_x().ValueOr(false))
+      return false;
+    if (has_offset_two_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_offset_two_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_offset_two_x().ValueOr(false) &&
+        has_offset_two_x().ValueOr(false) &&
+        !offset_two_x().UncheckedEquals(emboss_reserved_local_other.offset_two_x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_size_two_x().ValueOr(false) &&
+        !has_size_two_x().ValueOr(false))
+      return false;
+    if (has_size_two_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_size_two_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_size_two_x().ValueOr(false) &&
+        has_size_two_x().ValueOr(false) &&
+        !size_two_x().UncheckedEquals(emboss_reserved_local_other.size_two_x()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericStructureWithValuesInLocationView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericStructureWithValuesInLocationView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericStructureWithValuesInLocationView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "offset_two_x") {
+        if (!offset_two_x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "size_two_x") {
+        if (!size_two_x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_two_x().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          two_x().IsAggregate() || two_x().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# two_x: ");
+        two_x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# two_x: UNREADABLE\n");
+      }
+    }
+
+    if (has_offset_two_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          offset_two_x().IsAggregate() || offset_two_x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("offset_two_x: ");
+        offset_two_x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !offset_two_x().IsAggregate() && !offset_two_x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# offset_two_x: UNREADABLE\n");
+      }
+    }
+
+    if (has_size_two_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          size_two_x().IsAggregate() || size_two_x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("size_two_x: ");
+        size_two_x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !size_two_x().IsAggregate() && !size_two_x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# size_two_x: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  class EmbossReservedVirtualTwoXView final {
+   public:
+    using ValueType = ::std::int64_t;
+
+    explicit EmbossReservedVirtualTwoXView(
+        const GenericStructureWithValuesInLocationView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualTwoXView() = delete;
+    EmbossReservedVirtualTwoXView(const EmbossReservedVirtualTwoXView &) = default;
+    EmbossReservedVirtualTwoXView(EmbossReservedVirtualTwoXView &&) = default;
+    EmbossReservedVirtualTwoXView &operator=(const EmbossReservedVirtualTwoXView &) =
+        default;
+    EmbossReservedVirtualTwoXView &operator=(EmbossReservedVirtualTwoXView &&) =
+        default;
+    ~EmbossReservedVirtualTwoXView() = default;
+
+    ::std::int64_t Read() const {
+      EMBOSS_CHECK(view_.has_two_x().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int64_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int64_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::uint32_t>(static_cast</**/::std::uint32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::uint32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Product</**/::std::int64_t, ::std::int64_t, ::std::uint32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)));
+
+      return emboss_reserved_local_subexpr_3;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int64_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericStructureWithValuesInLocationView view_;
+  };
+  EmbossReservedVirtualTwoXView two_x() const;
+  ::emboss::support::Maybe<bool> has_two_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/2, 0>>, 32>>
+
+ offset_two_x() const;
+  ::emboss::support::Maybe<bool> has_offset_two_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+ size_two_x() const;
+  ::emboss::support::Maybe<bool> has_size_two_x() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int64_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericStructureWithValuesInLocationView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int64_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int64_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int64_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.two_x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int64_t>(static_cast</**/::std::int64_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int64_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int64_t, ::std::int64_t, ::std::int64_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int64_t, ::std::int64_t, bool, ::std::int64_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Sum</**/::std::int64_t, ::std::int64_t, ::std::int32_t, ::std::int64_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)), emboss_reserved_local_subexpr_2);
+      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Choice</**/::std::int64_t, ::std::int64_t, bool, ::std::int64_t, ::std::int32_t>(::emboss::support::Maybe</**/bool>(true), emboss_reserved_local_subexpr_5, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::Maximum</**/::std::int64_t, ::std::int64_t, ::std::int32_t, ::std::int32_t, ::std::int64_t, ::std::int64_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)), emboss_reserved_local_subexpr_4, emboss_reserved_local_subexpr_6);
+
+      return emboss_reserved_local_subexpr_7;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int64_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericStructureWithValuesInLocationView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int64_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int64_t Read();
+    static constexpr ::std::int64_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericStructureWithValuesInLocationView;
+};
+using StructureWithValuesInLocationView =
+    GenericStructureWithValuesInLocationView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using StructureWithValuesInLocationWriter =
+    GenericStructureWithValuesInLocationView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructureWithValuesInLocationView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericStructureWithValuesInLocationView<
+    GenericStructureWithValuesInLocationView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericStructureWithValuesInLocationView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeStructureWithValuesInLocationView( T &&emboss_reserved_local_arg) {
+  return GenericStructureWithValuesInLocationView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericStructureWithValuesInLocationView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeStructureWithValuesInLocationView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericStructureWithValuesInLocationView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericStructureWithValuesInLocationView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedStructureWithValuesInLocationView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericStructureWithValuesInLocationView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace StructureWithBoolValue {
+
+}  // namespace StructureWithBoolValue
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructureWithBoolValueView;
+
+template <class Storage>
+class GenericStructureWithBoolValueView final {
+ public:
+  GenericStructureWithBoolValueView() : backing_() {}
+  explicit GenericStructureWithBoolValueView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructureWithBoolValueView(
+      const GenericStructureWithBoolValueView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericStructureWithBoolValueView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericStructureWithBoolValueView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericStructureWithBoolValueView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructureWithBoolValueView<Storage> &operator=(
+      const GenericStructureWithBoolValueView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_x_is_ten().Known()) return false;
+    if (has_x_is_ten().ValueOrDefault() && !x_is_ten().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericStructureWithBoolValueView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericStructureWithBoolValueView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericStructureWithBoolValueView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericStructureWithBoolValueView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericStructureWithBoolValueView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_x_is_ten().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x_is_ten().IsAggregate() || x_is_ten().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# x_is_ten: ");
+        x_is_ten().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x_is_ten: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  class EmbossReservedVirtualXIsTenView final {
+   public:
+    using ValueType = bool;
+
+    explicit EmbossReservedVirtualXIsTenView(
+        const GenericStructureWithBoolValueView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualXIsTenView() = delete;
+    EmbossReservedVirtualXIsTenView(const EmbossReservedVirtualXIsTenView &) = default;
+    EmbossReservedVirtualXIsTenView(EmbossReservedVirtualXIsTenView &&) = default;
+    EmbossReservedVirtualXIsTenView &operator=(const EmbossReservedVirtualXIsTenView &) =
+        default;
+    EmbossReservedVirtualXIsTenView &operator=(EmbossReservedVirtualXIsTenView &&) =
+        default;
+    ~EmbossReservedVirtualXIsTenView() = default;
+
+    bool Read() const {
+      EMBOSS_CHECK(view_.has_x_is_ten().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    bool UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteBooleanViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ bool> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::uint32_t>(static_cast</**/::std::uint32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::uint32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Equal</**/::std::uint32_t, bool, ::std::uint32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)));
+
+      return emboss_reserved_local_subexpr_3;
+    }
+
+    static constexpr bool ValueIsOk(
+        bool emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericStructureWithBoolValueView view_;
+  };
+  EmbossReservedVirtualXIsTenView x_is_ten() const;
+  ::emboss::support::Maybe<bool> has_x_is_ten() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericStructureWithBoolValueView;
+};
+using StructureWithBoolValueView =
+    GenericStructureWithBoolValueView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using StructureWithBoolValueWriter =
+    GenericStructureWithBoolValueView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructureWithBoolValueView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericStructureWithBoolValueView<
+    GenericStructureWithBoolValueView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericStructureWithBoolValueView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeStructureWithBoolValueView( T &&emboss_reserved_local_arg) {
+  return GenericStructureWithBoolValueView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericStructureWithBoolValueView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeStructureWithBoolValueView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericStructureWithBoolValueView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericStructureWithBoolValueView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedStructureWithBoolValueView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericStructureWithBoolValueView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace StructureWithEnumValue {
+enum class Category : ::std::uint64_t {
+  SMALL = static_cast</**/::std::int32_t>(1LL),
+  LARGE = static_cast</**/::std::int32_t>(2LL),
+
+};
+template <class Enum>
+class EnumTraits;
+
+template <>
+class EnumTraits<Category> final {
+ public:
+  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
+                                   Category *emboss_reserved_local_result) {
+    if (emboss_reserved_local_name == nullptr) return false;
+    if (!strcmp("SMALL", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Category::SMALL;
+      return true;
+    }
+
+    if (!strcmp("LARGE", emboss_reserved_local_name)) {
+      *emboss_reserved_local_result = Category::LARGE;
+      return true;
+    }
+
+    return false;
+  }
+
+  static const char *TryToGetNameFromEnum(
+      Category emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Category::SMALL: return "SMALL";
+
+      case Category::LARGE: return "LARGE";
+
+      default: return nullptr;
+    }
+  }
+
+  static bool EnumIsKnown(Category emboss_reserved_local_value) {
+    switch (emboss_reserved_local_value) {
+      case Category::SMALL: return true;
+
+      case Category::LARGE: return true;
+
+      default:
+        return false;
+    }
+  }
+
+  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
+                                       Category emboss_reserved_local_value) {
+    const char *emboss_reserved_local_name =
+        TryToGetNameFromEnum(emboss_reserved_local_value);
+    if (emboss_reserved_local_name == nullptr) {
+      emboss_reserved_local_os
+          << static_cast</**/ ::std::underlying_type<Category>::type>(
+                 emboss_reserved_local_value);
+    } else {
+      emboss_reserved_local_os << emboss_reserved_local_name;
+    }
+    return emboss_reserved_local_os;
+  }
+};
+
+static inline bool TryToGetEnumFromName(
+    const char *emboss_reserved_local_name,
+    Category *emboss_reserved_local_result) {
+  return EnumTraits<Category>::TryToGetEnumFromName(
+      emboss_reserved_local_name, emboss_reserved_local_result);
+}
+
+static inline const char *TryToGetNameFromEnum(
+    Category emboss_reserved_local_value) {
+  return EnumTraits<Category>::TryToGetNameFromEnum(
+      emboss_reserved_local_value);
+}
+
+static inline bool EnumIsKnown(Category emboss_reserved_local_value) {
+  return EnumTraits<Category>::EnumIsKnown(emboss_reserved_local_value);
+}
+
+static inline ::std::ostream &operator<<(
+    ::std::ostream &emboss_reserved_local_os,
+    Category emboss_reserved_local_value) {
+  return EnumTraits<Category>::SendToOstream(emboss_reserved_local_os,
+                                             emboss_reserved_local_value);
+}
+
+}  // namespace StructureWithEnumValue
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructureWithEnumValueView;
+
+template <class Storage>
+class GenericStructureWithEnumValueView final {
+ public:
+  GenericStructureWithEnumValueView() : backing_() {}
+  explicit GenericStructureWithEnumValueView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructureWithEnumValueView(
+      const GenericStructureWithEnumValueView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericStructureWithEnumValueView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericStructureWithEnumValueView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericStructureWithEnumValueView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructureWithEnumValueView<Storage> &operator=(
+      const GenericStructureWithEnumValueView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+    using Category = ::emboss::test::StructureWithEnumValue::Category;
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_x_size().Known()) return false;
+    if (has_x_size().ValueOrDefault() && !x_size().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericStructureWithEnumValueView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericStructureWithEnumValueView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericStructureWithEnumValueView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericStructureWithEnumValueView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericStructureWithEnumValueView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_x_size().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x_size().IsAggregate() || x_size().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# x_size: ");
+        x_size().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x_size: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  class EmbossReservedVirtualXSizeView final {
+   public:
+    using ValueType = ::emboss::test::StructureWithEnumValue::Category;
+
+    explicit EmbossReservedVirtualXSizeView(
+        const GenericStructureWithEnumValueView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualXSizeView() = delete;
+    EmbossReservedVirtualXSizeView(const EmbossReservedVirtualXSizeView &) = default;
+    EmbossReservedVirtualXSizeView(EmbossReservedVirtualXSizeView &&) = default;
+    EmbossReservedVirtualXSizeView &operator=(const EmbossReservedVirtualXSizeView &) =
+        default;
+    EmbossReservedVirtualXSizeView &operator=(EmbossReservedVirtualXSizeView &&) =
+        default;
+    ~EmbossReservedVirtualXSizeView() = default;
+
+    ::emboss::test::StructureWithEnumValue::Category Read() const {
+      EMBOSS_CHECK(view_.has_x_size().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::emboss::test::StructureWithEnumValue::Category UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteEnumViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::emboss::test::StructureWithEnumValue::Category> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::uint32_t>(static_cast</**/::std::uint32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::uint32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::LessThan</**/::std::uint32_t, bool, ::std::uint32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(100LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::emboss::test::StructureWithEnumValue::Category, ::emboss::test::StructureWithEnumValue::Category, bool, ::emboss::test::StructureWithEnumValue::Category, ::emboss::test::StructureWithEnumValue::Category>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::emboss::test::StructureWithEnumValue::Category>(static_cast</**/::emboss::test::StructureWithEnumValue::Category>(1)), ::emboss::support::Maybe</**/::emboss::test::StructureWithEnumValue::Category>(static_cast</**/::emboss::test::StructureWithEnumValue::Category>(2)));
+
+      return emboss_reserved_local_subexpr_4;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::emboss::test::StructureWithEnumValue::Category emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericStructureWithEnumValueView view_;
+  };
+  EmbossReservedVirtualXSizeView x_size() const;
+  ::emboss::support::Maybe<bool> has_x_size() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericStructureWithEnumValueView;
+};
+using StructureWithEnumValueView =
+    GenericStructureWithEnumValueView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using StructureWithEnumValueWriter =
+    GenericStructureWithEnumValueView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructureWithEnumValueView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericStructureWithEnumValueView<
+    GenericStructureWithEnumValueView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericStructureWithEnumValueView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeStructureWithEnumValueView( T &&emboss_reserved_local_arg) {
+  return GenericStructureWithEnumValueView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericStructureWithEnumValueView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeStructureWithEnumValueView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericStructureWithEnumValueView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericStructureWithEnumValueView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedStructureWithEnumValueView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericStructureWithEnumValueView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace StructureWithBitsWithValue {
+
+}  // namespace StructureWithBitsWithValue
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructureWithBitsWithValueView;
+
+template <class Storage>
+class GenericStructureWithBitsWithValueView final {
+ public:
+  GenericStructureWithBitsWithValueView() : backing_() {}
+  explicit GenericStructureWithBitsWithValueView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructureWithBitsWithValueView(
+      const GenericStructureWithBitsWithValueView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericStructureWithBitsWithValueView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericStructureWithBitsWithValueView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericStructureWithBitsWithValueView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructureWithBitsWithValueView<Storage> &operator=(
+      const GenericStructureWithBitsWithValueView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_b().Known()) return false;
+    if (has_b().ValueOrDefault() && !b().Ok()) return false;
+
+
+    if (!has_alias_of_b_sum().Known()) return false;
+    if (has_alias_of_b_sum().ValueOrDefault() && !alias_of_b_sum().Ok()) return false;
+
+
+    if (!has_alias_of_b_a().Known()) return false;
+    if (has_alias_of_b_a().ValueOrDefault() && !alias_of_b_a().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericStructureWithBitsWithValueView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_b().Known()) return false;
+    if (!emboss_reserved_local_other.has_b().Known()) return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        !has_b().ValueOrDefault())
+      return false;
+    if (has_b().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_b().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        has_b().ValueOrDefault() &&
+        !b().Equals(emboss_reserved_local_other.b()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericStructureWithBitsWithValueView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        !has_b().ValueOr(false))
+      return false;
+    if (has_b().ValueOr(false) &&
+        !emboss_reserved_local_other.has_b().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        has_b().ValueOr(false) &&
+        !b().UncheckedEquals(emboss_reserved_local_other.b()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericStructureWithBitsWithValueView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericStructureWithBitsWithValueView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericStructureWithBitsWithValueView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "b") {
+        if (!b().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "alias_of_b_a") {
+        if (!alias_of_b_a().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_b().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b().IsAggregate() || b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("b: ");
+        b().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !b().IsAggregate() && !b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b: UNREADABLE\n");
+      }
+    }
+
+    if (has_alias_of_b_sum().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          alias_of_b_sum().IsAggregate() || alias_of_b_sum().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# alias_of_b_sum: ");
+        alias_of_b_sum().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# alias_of_b_sum: UNREADABLE\n");
+      }
+    }
+
+    if (has_alias_of_b_a().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          alias_of_b_a().IsAggregate() || alias_of_b_a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("alias_of_b_a: ");
+        alias_of_b_a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !alias_of_b_a().IsAggregate() && !alias_of_b_a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# alias_of_b_a: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::test::GenericBitsWithValueView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ b() const;
+  ::emboss::support::Maybe<bool> has_b() const;
+
+ public:
+  class EmbossReservedVirtualAliasOfBSumView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedVirtualAliasOfBSumView(
+        const GenericStructureWithBitsWithValueView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualAliasOfBSumView() = delete;
+    EmbossReservedVirtualAliasOfBSumView(const EmbossReservedVirtualAliasOfBSumView &) = default;
+    EmbossReservedVirtualAliasOfBSumView(EmbossReservedVirtualAliasOfBSumView &&) = default;
+    EmbossReservedVirtualAliasOfBSumView &operator=(const EmbossReservedVirtualAliasOfBSumView &) =
+        default;
+    EmbossReservedVirtualAliasOfBSumView &operator=(EmbossReservedVirtualAliasOfBSumView &&) =
+        default;
+    ~EmbossReservedVirtualAliasOfBSumView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_alias_of_b_sum().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.b().sum();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+
+      return emboss_reserved_local_subexpr_2;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericStructureWithBitsWithValueView view_;
+  };
+  EmbossReservedVirtualAliasOfBSumView alias_of_b_sum() const;
+  ::emboss::support::Maybe<bool> has_alias_of_b_sum() const;
+
+ public:
+  auto alias_of_b_a() const -> decltype(this->b().a()) {
+   return has_alias_of_b_a().ValueOrDefault() ? b().a()
+                                          : decltype(this->b().a())();
+  }
+  ::emboss::support::Maybe<bool> has_alias_of_b_a() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericStructureWithBitsWithValueView;
+};
+using StructureWithBitsWithValueView =
+    GenericStructureWithBitsWithValueView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using StructureWithBitsWithValueWriter =
+    GenericStructureWithBitsWithValueView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructureWithBitsWithValueView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericStructureWithBitsWithValueView<
+    GenericStructureWithBitsWithValueView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericStructureWithBitsWithValueView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeStructureWithBitsWithValueView( T &&emboss_reserved_local_arg) {
+  return GenericStructureWithBitsWithValueView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericStructureWithBitsWithValueView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeStructureWithBitsWithValueView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericStructureWithBitsWithValueView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericStructureWithBitsWithValueView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedStructureWithBitsWithValueView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericStructureWithBitsWithValueView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace BitsWithValue {
+
+}  // namespace BitsWithValue
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericBitsWithValueView;
+
+template <class Storage>
+class GenericBitsWithValueView final {
+ public:
+  GenericBitsWithValueView() : backing_() {}
+  explicit GenericBitsWithValueView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericBitsWithValueView(
+      const GenericBitsWithValueView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericBitsWithValueView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericBitsWithValueView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericBitsWithValueView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericBitsWithValueView<Storage> &operator=(
+      const GenericBitsWithValueView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_a().Known()) return false;
+    if (has_a().ValueOrDefault() && !a().Ok()) return false;
+
+
+    if (!has_b().Known()) return false;
+    if (has_b().ValueOrDefault() && !b().Ok()) return false;
+
+
+    if (!has_sum().Known()) return false;
+    if (has_sum().ValueOrDefault() && !sum().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBits().Known()) return false;
+    if (has_IntrinsicSizeInBits().ValueOrDefault() && !IntrinsicSizeInBits().Ok()) return false;
+
+
+    if (!has_MaxSizeInBits().Known()) return false;
+    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok()) return false;
+
+
+    if (!has_MinSizeInBits().Known()) return false;
+    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBits().Ok() &&
+           backing_.SizeInBits() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBits().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBits() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBits().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBits().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericBitsWithValueView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_a().Known()) return false;
+    if (!emboss_reserved_local_other.has_a().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        !has_a().ValueOrDefault())
+      return false;
+    if (has_a().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOrDefault() &&
+        has_a().ValueOrDefault() &&
+        !a().Equals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (!has_b().Known()) return false;
+    if (!emboss_reserved_local_other.has_b().Known()) return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        !has_b().ValueOrDefault())
+      return false;
+    if (has_b().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_b().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOrDefault() &&
+        has_b().ValueOrDefault() &&
+        !b().Equals(emboss_reserved_local_other.b()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericBitsWithValueView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        !has_a().ValueOr(false))
+      return false;
+    if (has_a().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a().ValueOr(false) &&
+        has_a().ValueOr(false) &&
+        !a().UncheckedEquals(emboss_reserved_local_other.a()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        !has_b().ValueOr(false))
+      return false;
+    if (has_b().ValueOr(false) &&
+        !emboss_reserved_local_other.has_b().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_b().ValueOr(false) &&
+        has_b().ValueOr(false) &&
+        !b().UncheckedEquals(emboss_reserved_local_other.b()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericBitsWithValueView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericBitsWithValueView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericBitsWithValueView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "a") {
+        if (!a().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "b") {
+        if (!b().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_a().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a().IsAggregate() || a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a: ");
+        a().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a().IsAggregate() && !a().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a: UNREADABLE\n");
+      }
+    }
+
+    if (has_b().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          b().IsAggregate() || b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("b: ");
+        b().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !b().IsAggregate() && !b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# b: UNREADABLE\n");
+      }
+    }
+
+    if (has_sum().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          sum().IsAggregate() || sum().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# sum: ");
+        sum().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# sum: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ a() const;
+  ::emboss::support::Maybe<bool> has_a() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 16>>
+
+ b() const;
+  ::emboss::support::Maybe<bool> has_b() const;
+
+ public:
+  class EmbossReservedVirtualSumView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedVirtualSumView(
+        const GenericBitsWithValueView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualSumView() = delete;
+    EmbossReservedVirtualSumView(const EmbossReservedVirtualSumView &) = default;
+    EmbossReservedVirtualSumView(EmbossReservedVirtualSumView &&) = default;
+    EmbossReservedVirtualSumView &operator=(const EmbossReservedVirtualSumView &) =
+        default;
+    EmbossReservedVirtualSumView &operator=(EmbossReservedVirtualSumView &&) =
+        default;
+    ~EmbossReservedVirtualSumView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_sum().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.a();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = view_.b();
+      const auto emboss_reserved_local_subexpr_4 = (emboss_reserved_local_subexpr_3.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_3.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_4);
+
+      return emboss_reserved_local_subexpr_5;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericBitsWithValueView view_;
+  };
+  EmbossReservedVirtualSumView sum() const;
+  ::emboss::support::Maybe<bool> has_sum() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView IntrinsicSizeInBits() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBitsView() {}
+    EmbossReservedDollarVirtualMaxSizeInBitsView(const EmbossReservedDollarVirtualMaxSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView(EmbossReservedDollarVirtualMaxSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(const EmbossReservedDollarVirtualMaxSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(EmbossReservedDollarVirtualMaxSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBitsView MaxSizeInBits() {
+    return EmbossReservedDollarVirtualMaxSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBitsView() {}
+    EmbossReservedDollarVirtualMinSizeInBitsView(const EmbossReservedDollarVirtualMinSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView(EmbossReservedDollarVirtualMinSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(const EmbossReservedDollarVirtualMinSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(EmbossReservedDollarVirtualMinSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBitsView MinSizeInBits() {
+    return EmbossReservedDollarVirtualMinSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericBitsWithValueView;
+};
+using BitsWithValueView =
+    GenericBitsWithValueView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using BitsWithValueWriter =
+    GenericBitsWithValueView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericBitsWithValueView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericBitsWithValueView<
+    GenericBitsWithValueView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericBitsWithValueView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeBitsWithValueView( T &&emboss_reserved_local_arg) {
+  return GenericBitsWithValueView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericBitsWithValueView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeBitsWithValueView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericBitsWithValueView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericBitsWithValueView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedBitsWithValueView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericBitsWithValueView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace StructureUsingForeignConstants {
+
+}  // namespace StructureUsingForeignConstants
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructureUsingForeignConstantsView;
+
+template <class Storage>
+class GenericStructureUsingForeignConstantsView final {
+ public:
+  GenericStructureUsingForeignConstantsView() : backing_() {}
+  explicit GenericStructureUsingForeignConstantsView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructureUsingForeignConstantsView(
+      const GenericStructureUsingForeignConstantsView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericStructureUsingForeignConstantsView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericStructureUsingForeignConstantsView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericStructureUsingForeignConstantsView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericStructureUsingForeignConstantsView<Storage> &operator=(
+      const GenericStructureUsingForeignConstantsView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_one_hundred().Known()) return false;
+    if (has_one_hundred().ValueOrDefault() && !one_hundred().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericStructureUsingForeignConstantsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericStructureUsingForeignConstantsView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericStructureUsingForeignConstantsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericStructureUsingForeignConstantsView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericStructureUsingForeignConstantsView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_one_hundred().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          one_hundred().IsAggregate() || one_hundred().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# one_hundred: ");
+        one_hundred().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# one_hundred: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 32>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  class EmbossReservedVirtualOneHundredView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedVirtualOneHundredView() {}
+    EmbossReservedVirtualOneHundredView(const EmbossReservedVirtualOneHundredView &) = default;
+    EmbossReservedVirtualOneHundredView(EmbossReservedVirtualOneHundredView &&) = default;
+    EmbossReservedVirtualOneHundredView &operator=(const EmbossReservedVirtualOneHundredView &) =
+        default;
+    EmbossReservedVirtualOneHundredView &operator=(EmbossReservedVirtualOneHundredView &&) =
+        default;
+    ~EmbossReservedVirtualOneHundredView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedVirtualOneHundredView one_hundred() {
+    return EmbossReservedVirtualOneHundredView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_one_hundred() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericStructureUsingForeignConstantsView;
+};
+using StructureUsingForeignConstantsView =
+    GenericStructureUsingForeignConstantsView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using StructureUsingForeignConstantsWriter =
+    GenericStructureUsingForeignConstantsView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericStructureUsingForeignConstantsView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericStructureUsingForeignConstantsView<
+    GenericStructureUsingForeignConstantsView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericStructureUsingForeignConstantsView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeStructureUsingForeignConstantsView( T &&emboss_reserved_local_arg) {
+  return GenericStructureUsingForeignConstantsView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericStructureUsingForeignConstantsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeStructureUsingForeignConstantsView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericStructureUsingForeignConstantsView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericStructureUsingForeignConstantsView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedStructureUsingForeignConstantsView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericStructureUsingForeignConstantsView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace SubfieldOfAlias {
+
+
+
+
+namespace Header {
+
+}  // namespace Header
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericHeaderView;
+
+template <class Storage>
+class GenericHeaderView final {
+ public:
+  GenericHeaderView() : backing_() {}
+  explicit GenericHeaderView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericHeaderView(
+      const GenericHeaderView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericHeaderView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericHeaderView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericHeaderView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericHeaderView<Storage> &operator=(
+      const GenericHeaderView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_size().Known()) return false;
+    if (has_size().ValueOrDefault() && !size().Ok()) return false;
+
+
+    if (!has_message_id().Known()) return false;
+    if (has_message_id().ValueOrDefault() && !message_id().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericHeaderView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_size().Known()) return false;
+    if (!emboss_reserved_local_other.has_size().Known()) return false;
+
+    if (emboss_reserved_local_other.has_size().ValueOrDefault() &&
+        !has_size().ValueOrDefault())
+      return false;
+    if (has_size().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_size().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_size().ValueOrDefault() &&
+        has_size().ValueOrDefault() &&
+        !size().Equals(emboss_reserved_local_other.size()))
+      return false;
+
+
+
+    if (!has_message_id().Known()) return false;
+    if (!emboss_reserved_local_other.has_message_id().Known()) return false;
+
+    if (emboss_reserved_local_other.has_message_id().ValueOrDefault() &&
+        !has_message_id().ValueOrDefault())
+      return false;
+    if (has_message_id().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_message_id().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_message_id().ValueOrDefault() &&
+        has_message_id().ValueOrDefault() &&
+        !message_id().Equals(emboss_reserved_local_other.message_id()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericHeaderView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_size().ValueOr(false) &&
+        !has_size().ValueOr(false))
+      return false;
+    if (has_size().ValueOr(false) &&
+        !emboss_reserved_local_other.has_size().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_size().ValueOr(false) &&
+        has_size().ValueOr(false) &&
+        !size().UncheckedEquals(emboss_reserved_local_other.size()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_message_id().ValueOr(false) &&
+        !has_message_id().ValueOr(false))
+      return false;
+    if (has_message_id().ValueOr(false) &&
+        !emboss_reserved_local_other.has_message_id().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_message_id().ValueOr(false) &&
+        has_message_id().ValueOr(false) &&
+        !message_id().UncheckedEquals(emboss_reserved_local_other.message_id()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericHeaderView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericHeaderView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericHeaderView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "size") {
+        if (!size().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "message_id") {
+        if (!message_id().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_size().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          size().IsAggregate() || size().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("size: ");
+        size().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !size().IsAggregate() && !size().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# size: UNREADABLE\n");
+      }
+    }
+
+    if (has_message_id().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          message_id().IsAggregate() || message_id().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("message_id: ");
+        message_id().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !message_id().IsAggregate() && !message_id().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# message_id: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 16>>
+
+ size() const;
+  ::emboss::support::Maybe<bool> has_size() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 16>>
+
+ message_id() const;
+  ::emboss::support::Maybe<bool> has_message_id() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericHeaderView;
+};
+using HeaderView =
+    GenericHeaderView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using HeaderWriter =
+    GenericHeaderView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericHeaderView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericHeaderView<
+    GenericHeaderView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericHeaderView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeHeaderView( T &&emboss_reserved_local_arg) {
+  return GenericHeaderView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericHeaderView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeHeaderView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericHeaderView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericHeaderView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedHeaderView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericHeaderView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+}  // namespace SubfieldOfAlias
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericSubfieldOfAliasView;
+
+template <class Storage>
+class GenericSubfieldOfAliasView final {
+ public:
+  GenericSubfieldOfAliasView() : backing_() {}
+  explicit GenericSubfieldOfAliasView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericSubfieldOfAliasView(
+      const GenericSubfieldOfAliasView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericSubfieldOfAliasView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericSubfieldOfAliasView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericSubfieldOfAliasView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericSubfieldOfAliasView<Storage> &operator=(
+      const GenericSubfieldOfAliasView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_header().Known()) return false;
+    if (has_header().ValueOrDefault() && !header().Ok()) return false;
+
+
+    if (!has_h().Known()) return false;
+    if (has_h().ValueOrDefault() && !h().Ok()) return false;
+
+
+    if (!has_size().Known()) return false;
+    if (has_size().ValueOrDefault() && !size().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericSubfieldOfAliasView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_header().Known()) return false;
+    if (!emboss_reserved_local_other.has_header().Known()) return false;
+
+    if (emboss_reserved_local_other.has_header().ValueOrDefault() &&
+        !has_header().ValueOrDefault())
+      return false;
+    if (has_header().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_header().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_header().ValueOrDefault() &&
+        has_header().ValueOrDefault() &&
+        !header().Equals(emboss_reserved_local_other.header()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericSubfieldOfAliasView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_header().ValueOr(false) &&
+        !has_header().ValueOr(false))
+      return false;
+    if (has_header().ValueOr(false) &&
+        !emboss_reserved_local_other.has_header().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_header().ValueOr(false) &&
+        has_header().ValueOr(false) &&
+        !header().UncheckedEquals(emboss_reserved_local_other.header()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericSubfieldOfAliasView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericSubfieldOfAliasView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericSubfieldOfAliasView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "header") {
+        if (!header().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "h") {
+        if (!h().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "size") {
+        if (!size().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_header().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          header().IsAggregate() || header().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("header: ");
+        header().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !header().IsAggregate() && !header().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# header: UNREADABLE\n");
+      }
+    }
+
+    if (has_h().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          h().IsAggregate() || h().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("h: ");
+        h().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !h().IsAggregate() && !h().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# h: UNREADABLE\n");
+      }
+    }
+
+    if (has_size().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          size().IsAggregate() || size().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("size: ");
+        size().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !size().IsAggregate() && !size().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# size: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::test::SubfieldOfAlias::GenericHeaderView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ header() const;
+  ::emboss::support::Maybe<bool> has_header() const;
+
+ public:
+  auto h() const -> decltype(this->header()) {
+   return has_h().ValueOrDefault() ? header()
+                                          : decltype(this->header())();
+  }
+  ::emboss::support::Maybe<bool> has_h() const;
+
+ public:
+  auto size() const -> decltype(this->h().size()) {
+   return has_size().ValueOrDefault() ? h().size()
+                                          : decltype(this->h().size())();
+  }
+  ::emboss::support::Maybe<bool> has_size() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericSubfieldOfAliasView;
+};
+using SubfieldOfAliasView =
+    GenericSubfieldOfAliasView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using SubfieldOfAliasWriter =
+    GenericSubfieldOfAliasView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericSubfieldOfAliasView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericSubfieldOfAliasView<
+    GenericSubfieldOfAliasView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericSubfieldOfAliasView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeSubfieldOfAliasView( T &&emboss_reserved_local_arg) {
+  return GenericSubfieldOfAliasView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericSubfieldOfAliasView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeSubfieldOfAliasView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericSubfieldOfAliasView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericSubfieldOfAliasView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedSubfieldOfAliasView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericSubfieldOfAliasView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace RestrictedAlias {
+
+}  // namespace RestrictedAlias
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericRestrictedAliasView;
+
+template <class Storage>
+class GenericRestrictedAliasView final {
+ public:
+  GenericRestrictedAliasView() : backing_() {}
+  explicit GenericRestrictedAliasView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericRestrictedAliasView(
+      const GenericRestrictedAliasView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericRestrictedAliasView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericRestrictedAliasView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericRestrictedAliasView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericRestrictedAliasView<Storage> &operator=(
+      const GenericRestrictedAliasView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_a_b().Known()) return false;
+    if (has_a_b().ValueOrDefault() && !a_b().Ok()) return false;
+
+
+    if (!has_alias_switch().Known()) return false;
+    if (has_alias_switch().ValueOrDefault() && !alias_switch().Ok()) return false;
+
+
+    if (!has_a_b_alias().Known()) return false;
+    if (has_a_b_alias().ValueOrDefault() && !a_b_alias().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericRestrictedAliasView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_a_b().Known()) return false;
+    if (!emboss_reserved_local_other.has_a_b().Known()) return false;
+
+    if (emboss_reserved_local_other.has_a_b().ValueOrDefault() &&
+        !has_a_b().ValueOrDefault())
+      return false;
+    if (has_a_b().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_a_b().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_a_b().ValueOrDefault() &&
+        has_a_b().ValueOrDefault() &&
+        !a_b().Equals(emboss_reserved_local_other.a_b()))
+      return false;
+
+
+
+    if (!has_alias_switch().Known()) return false;
+    if (!emboss_reserved_local_other.has_alias_switch().Known()) return false;
+
+    if (emboss_reserved_local_other.has_alias_switch().ValueOrDefault() &&
+        !has_alias_switch().ValueOrDefault())
+      return false;
+    if (has_alias_switch().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_alias_switch().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_alias_switch().ValueOrDefault() &&
+        has_alias_switch().ValueOrDefault() &&
+        !alias_switch().Equals(emboss_reserved_local_other.alias_switch()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericRestrictedAliasView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_a_b().ValueOr(false) &&
+        !has_a_b().ValueOr(false))
+      return false;
+    if (has_a_b().ValueOr(false) &&
+        !emboss_reserved_local_other.has_a_b().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_a_b().ValueOr(false) &&
+        has_a_b().ValueOr(false) &&
+        !a_b().UncheckedEquals(emboss_reserved_local_other.a_b()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_alias_switch().ValueOr(false) &&
+        !has_alias_switch().ValueOr(false))
+      return false;
+    if (has_alias_switch().ValueOr(false) &&
+        !emboss_reserved_local_other.has_alias_switch().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_alias_switch().ValueOr(false) &&
+        has_alias_switch().ValueOr(false) &&
+        !alias_switch().UncheckedEquals(emboss_reserved_local_other.alias_switch()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericRestrictedAliasView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericRestrictedAliasView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericRestrictedAliasView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "a_b") {
+        if (!a_b().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "alias_switch") {
+        if (!alias_switch().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "a_b_alias") {
+        if (!a_b_alias().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_a_b().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a_b().IsAggregate() || a_b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a_b: ");
+        a_b().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a_b().IsAggregate() && !a_b().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a_b: UNREADABLE\n");
+      }
+    }
+
+    if (has_alias_switch().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          alias_switch().IsAggregate() || alias_switch().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("alias_switch: ");
+        alias_switch().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !alias_switch().IsAggregate() && !alias_switch().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# alias_switch: UNREADABLE\n");
+      }
+    }
+
+    if (has_a_b_alias().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          a_b_alias().IsAggregate() || a_b_alias().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("a_b_alias: ");
+        a_b_alias().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !a_b_alias().IsAggregate() && !a_b_alias().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# a_b_alias: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::test::GenericBitsWithValueView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ a_b() const;
+  ::emboss::support::Maybe<bool> has_a_b() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 8>>
+
+ alias_switch() const;
+  ::emboss::support::Maybe<bool> has_alias_switch() const;
+
+ public:
+  auto a_b_alias() const -> decltype(this->a_b()) {
+   return has_a_b_alias().ValueOrDefault() ? a_b()
+                                          : decltype(this->a_b())();
+  }
+  ::emboss::support::Maybe<bool> has_a_b_alias() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericRestrictedAliasView;
+};
+using RestrictedAliasView =
+    GenericRestrictedAliasView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using RestrictedAliasWriter =
+    GenericRestrictedAliasView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericRestrictedAliasView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericRestrictedAliasView<
+    GenericRestrictedAliasView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericRestrictedAliasView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeRestrictedAliasView( T &&emboss_reserved_local_arg) {
+  return GenericRestrictedAliasView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericRestrictedAliasView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeRestrictedAliasView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericRestrictedAliasView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericRestrictedAliasView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedRestrictedAliasView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericRestrictedAliasView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+
+namespace HasField {
+
+
+
+
+namespace X {
+
+}  // namespace X
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericXView;
+
+template <class Storage>
+class GenericXView final {
+ public:
+  GenericXView() : backing_() {}
+  explicit GenericXView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericXView(
+      const GenericXView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericXView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericXView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericXView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericXView<Storage> &operator=(
+      const GenericXView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_v().Known()) return false;
+    if (has_v().ValueOrDefault() && !v().Ok()) return false;
+
+
+    if (!has_y().Known()) return false;
+    if (has_y().ValueOrDefault() && !y().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericXView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_v().Known()) return false;
+    if (!emboss_reserved_local_other.has_v().Known()) return false;
+
+    if (emboss_reserved_local_other.has_v().ValueOrDefault() &&
+        !has_v().ValueOrDefault())
+      return false;
+    if (has_v().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_v().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_v().ValueOrDefault() &&
+        has_v().ValueOrDefault() &&
+        !v().Equals(emboss_reserved_local_other.v()))
+      return false;
+
+
+
+    if (!has_y().Known()) return false;
+    if (!emboss_reserved_local_other.has_y().Known()) return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
+        !has_y().ValueOrDefault())
+      return false;
+    if (has_y().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_y().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
+        has_y().ValueOrDefault() &&
+        !y().Equals(emboss_reserved_local_other.y()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericXView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_v().ValueOr(false) &&
+        !has_v().ValueOr(false))
+      return false;
+    if (has_v().ValueOr(false) &&
+        !emboss_reserved_local_other.has_v().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_v().ValueOr(false) &&
+        has_v().ValueOr(false) &&
+        !v().UncheckedEquals(emboss_reserved_local_other.v()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
+        !has_y().ValueOr(false))
+      return false;
+    if (has_y().ValueOr(false) &&
+        !emboss_reserved_local_other.has_y().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
+        has_y().ValueOr(false) &&
+        !y().UncheckedEquals(emboss_reserved_local_other.y()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericXView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericXView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericXView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "v") {
+        if (!v().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "y") {
+        if (!y().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_v().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          v().IsAggregate() || v().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("v: ");
+        v().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !v().IsAggregate() && !v().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# v: UNREADABLE\n");
+      }
+    }
+
+    if (has_y().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          y().IsAggregate() || y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("y: ");
+        y().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !y().IsAggregate() && !y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# y: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ v() const;
+  ::emboss::support::Maybe<bool> has_v() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ y() const;
+  ::emboss::support::Maybe<bool> has_y() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericXView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.v();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_4);
+
+      return emboss_reserved_local_subexpr_5;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericXView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericXView;
+};
+using XView =
+    GenericXView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using XWriter =
+    GenericXView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericXView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericXView<
+    GenericXView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericXView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeXView( T &&emboss_reserved_local_arg) {
+  return GenericXView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericXView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeXView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericXView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericXView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedXView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericXView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+}  // namespace HasField
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericHasFieldView;
+
+template <class Storage>
+class GenericHasFieldView final {
+ public:
+  GenericHasFieldView() : backing_() {}
+  explicit GenericHasFieldView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericHasFieldView(
+      const GenericHasFieldView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericHasFieldView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericHasFieldView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericHasFieldView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericHasFieldView<Storage> &operator=(
+      const GenericHasFieldView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_z().Known()) return false;
+    if (has_z().ValueOrDefault() && !z().Ok()) return false;
+
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_y().Known()) return false;
+    if (has_y().ValueOrDefault() && !y().Ok()) return false;
+
+
+    if (!has_x_has_y().Known()) return false;
+    if (has_x_has_y().ValueOrDefault() && !x_has_y().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericHasFieldView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_z().Known()) return false;
+    if (!emboss_reserved_local_other.has_z().Known()) return false;
+
+    if (emboss_reserved_local_other.has_z().ValueOrDefault() &&
+        !has_z().ValueOrDefault())
+      return false;
+    if (has_z().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_z().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_z().ValueOrDefault() &&
+        has_z().ValueOrDefault() &&
+        !z().Equals(emboss_reserved_local_other.z()))
+      return false;
+
+
+
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericHasFieldView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_z().ValueOr(false) &&
+        !has_z().ValueOr(false))
+      return false;
+    if (has_z().ValueOr(false) &&
+        !emboss_reserved_local_other.has_z().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_z().ValueOr(false) &&
+        has_z().ValueOr(false) &&
+        !z().UncheckedEquals(emboss_reserved_local_other.z()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericHasFieldView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericHasFieldView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericHasFieldView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "z") {
+        if (!z().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "y") {
+        if (!y().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_z().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          z().IsAggregate() || z().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("z: ");
+        z().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !z().IsAggregate() && !z().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# z: UNREADABLE\n");
+      }
+    }
+
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_y().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          y().IsAggregate() || y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("y: ");
+        y().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !y().IsAggregate() && !y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# y: UNREADABLE\n");
+      }
+    }
+
+    if (has_x_has_y().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x_has_y().IsAggregate() || x_has_y().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# x_has_y: ");
+        x_has_y().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x_has_y: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ z() const;
+  ::emboss::support::Maybe<bool> has_z() const;
+
+ public:
+  typename ::emboss::test::HasField::GenericXView<typename Storage::template OffsetStorageType</**/0, 1>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  auto y() const -> decltype(this->x().y()) {
+   return has_y().ValueOrDefault() ? x().y()
+                                          : decltype(this->x().y())();
+  }
+  ::emboss::support::Maybe<bool> has_y() const;
+
+ public:
+  class EmbossReservedVirtualXHasYView final {
+   public:
+    using ValueType = bool;
+
+    explicit EmbossReservedVirtualXHasYView(
+        const GenericHasFieldView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualXHasYView() = delete;
+    EmbossReservedVirtualXHasYView(const EmbossReservedVirtualXHasYView &) = default;
+    EmbossReservedVirtualXHasYView(EmbossReservedVirtualXHasYView &&) = default;
+    EmbossReservedVirtualXHasYView &operator=(const EmbossReservedVirtualXHasYView &) =
+        default;
+    EmbossReservedVirtualXHasYView &operator=(EmbossReservedVirtualXHasYView &&) =
+        default;
+    ~EmbossReservedVirtualXHasYView() = default;
+
+    bool Read() const {
+      EMBOSS_CHECK(view_.has_x_has_y().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    bool UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteBooleanViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ bool> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x().has_y();
+
+      return emboss_reserved_local_subexpr_1;
+    }
+
+    static constexpr bool ValueIsOk(
+        bool emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericHasFieldView view_;
+  };
+  EmbossReservedVirtualXHasYView x_has_y() const;
+  ::emboss::support::Maybe<bool> has_x_has_y() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericHasFieldView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.z();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_4);
+
+      return emboss_reserved_local_subexpr_5;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericHasFieldView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericHasFieldView;
+};
+using HasFieldView =
+    GenericHasFieldView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using HasFieldWriter =
+    GenericHasFieldView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericHasFieldView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericHasFieldView<
+    GenericHasFieldView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericHasFieldView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeHasFieldView( T &&emboss_reserved_local_arg) {
+  return GenericHasFieldView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericHasFieldView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeHasFieldView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericHasFieldView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericHasFieldView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedHasFieldView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericHasFieldView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+namespace VirtualUnconditionallyUsesConditional {
+
+}  // namespace VirtualUnconditionallyUsesConditional
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericVirtualUnconditionallyUsesConditionalView;
+
+template <class Storage>
+class GenericVirtualUnconditionallyUsesConditionalView final {
+ public:
+  GenericVirtualUnconditionallyUsesConditionalView() : backing_() {}
+  explicit GenericVirtualUnconditionallyUsesConditionalView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericVirtualUnconditionallyUsesConditionalView(
+      const GenericVirtualUnconditionallyUsesConditionalView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericVirtualUnconditionallyUsesConditionalView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericVirtualUnconditionallyUsesConditionalView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericVirtualUnconditionallyUsesConditionalView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericVirtualUnconditionallyUsesConditionalView<Storage> &operator=(
+      const GenericVirtualUnconditionallyUsesConditionalView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_xc().Known()) return false;
+    if (has_xc().ValueOrDefault() && !xc().Ok()) return false;
+
+
+    if (!has_x_nor_xc().Known()) return false;
+    if (has_x_nor_xc().ValueOrDefault() && !x_nor_xc().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  ::std::size_t SizeInBytes() const {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }
+
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericVirtualUnconditionallyUsesConditionalView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_xc().Known()) return false;
+    if (!emboss_reserved_local_other.has_xc().Known()) return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        !has_xc().ValueOrDefault())
+      return false;
+    if (has_xc().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_xc().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOrDefault() &&
+        has_xc().ValueOrDefault() &&
+        !xc().Equals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericVirtualUnconditionallyUsesConditionalView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        !has_xc().ValueOr(false))
+      return false;
+    if (has_xc().ValueOr(false) &&
+        !emboss_reserved_local_other.has_xc().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_xc().ValueOr(false) &&
+        has_xc().ValueOr(false) &&
+        !xc().UncheckedEquals(emboss_reserved_local_other.xc()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericVirtualUnconditionallyUsesConditionalView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericVirtualUnconditionallyUsesConditionalView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericVirtualUnconditionallyUsesConditionalView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "xc") {
+        if (!xc().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_xc().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          xc().IsAggregate() || xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("xc: ");
+        xc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !xc().IsAggregate() && !xc().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# xc: UNREADABLE\n");
+      }
+    }
+
+    if (has_x_nor_xc().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x_nor_xc().IsAggregate() || x_nor_xc().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# x_nor_xc: ");
+        x_nor_xc().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x_nor_xc: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ xc() const;
+  ::emboss::support::Maybe<bool> has_xc() const;
+
+ public:
+  class EmbossReservedVirtualXNorXcView final {
+   public:
+    using ValueType = bool;
+
+    explicit EmbossReservedVirtualXNorXcView(
+        const GenericVirtualUnconditionallyUsesConditionalView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualXNorXcView() = delete;
+    EmbossReservedVirtualXNorXcView(const EmbossReservedVirtualXNorXcView &) = default;
+    EmbossReservedVirtualXNorXcView(EmbossReservedVirtualXNorXcView &&) = default;
+    EmbossReservedVirtualXNorXcView &operator=(const EmbossReservedVirtualXNorXcView &) =
+        default;
+    EmbossReservedVirtualXNorXcView &operator=(EmbossReservedVirtualXNorXcView &&) =
+        default;
+    ~EmbossReservedVirtualXNorXcView() = default;
+
+    bool Read() const {
+      EMBOSS_CHECK(view_.has_x_nor_xc().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    bool UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteBooleanViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ bool> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_4 = view_.xc();
+      const auto emboss_reserved_local_subexpr_5 = (emboss_reserved_local_subexpr_4.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_4.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_6 = ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_5, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_7 = ::emboss::support::And</**/bool, bool, bool, bool>(emboss_reserved_local_subexpr_3, emboss_reserved_local_subexpr_6);
+
+      return emboss_reserved_local_subexpr_7;
+    }
+
+    static constexpr bool ValueIsOk(
+        bool emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericVirtualUnconditionallyUsesConditionalView view_;
+  };
+  EmbossReservedVirtualXNorXcView x_nor_xc() const;
+  ::emboss::support::Maybe<bool> has_x_nor_xc() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+        const GenericVirtualUnconditionallyUsesConditionalView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Choice</**/::std::int32_t, ::std::int32_t, bool, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+      const auto emboss_reserved_local_subexpr_5 = ::emboss::support::Maximum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)), emboss_reserved_local_subexpr_4);
+
+      return emboss_reserved_local_subexpr_5;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericVirtualUnconditionallyUsesConditionalView view_;
+  };
+  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() const;
+  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericVirtualUnconditionallyUsesConditionalView;
+};
+using VirtualUnconditionallyUsesConditionalView =
+    GenericVirtualUnconditionallyUsesConditionalView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using VirtualUnconditionallyUsesConditionalWriter =
+    GenericVirtualUnconditionallyUsesConditionalView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericVirtualUnconditionallyUsesConditionalView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericVirtualUnconditionallyUsesConditionalView<
+    GenericVirtualUnconditionallyUsesConditionalView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericVirtualUnconditionallyUsesConditionalView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeVirtualUnconditionallyUsesConditionalView( T &&emboss_reserved_local_arg) {
+  return GenericVirtualUnconditionallyUsesConditionalView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericVirtualUnconditionallyUsesConditionalView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeVirtualUnconditionallyUsesConditionalView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericVirtualUnconditionallyUsesConditionalView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericVirtualUnconditionallyUsesConditionalView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedVirtualUnconditionallyUsesConditionalView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericVirtualUnconditionallyUsesConditionalView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace UsesSize {
+
+
+
+
+namespace R {
+
+}  // namespace R
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericRView;
+
+template <class Storage>
+class GenericRView final {
+ public:
+  GenericRView() : backing_() {}
+  explicit GenericRView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericRView(
+      const GenericRView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericRView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericRView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericRView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericRView<Storage> &operator=(
+      const GenericRView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_q().Known()) return false;
+    if (has_q().ValueOrDefault() && !q().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBits().Known()) return false;
+    if (has_IntrinsicSizeInBits().ValueOrDefault() && !IntrinsicSizeInBits().Ok()) return false;
+
+
+    if (!has_q_plus_bit_size().Known()) return false;
+    if (has_q_plus_bit_size().ValueOrDefault() && !q_plus_bit_size().Ok()) return false;
+
+
+    if (!has_MaxSizeInBits().Known()) return false;
+    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok()) return false;
+
+
+    if (!has_MinSizeInBits().Known()) return false;
+    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBits().Ok() &&
+           backing_.SizeInBits() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBits().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBits() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBits().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBits().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericRView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_q().Known()) return false;
+    if (!emboss_reserved_local_other.has_q().Known()) return false;
+
+    if (emboss_reserved_local_other.has_q().ValueOrDefault() &&
+        !has_q().ValueOrDefault())
+      return false;
+    if (has_q().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_q().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_q().ValueOrDefault() &&
+        has_q().ValueOrDefault() &&
+        !q().Equals(emboss_reserved_local_other.q()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericRView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_q().ValueOr(false) &&
+        !has_q().ValueOr(false))
+      return false;
+    if (has_q().ValueOr(false) &&
+        !emboss_reserved_local_other.has_q().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_q().ValueOr(false) &&
+        has_q().ValueOr(false) &&
+        !q().UncheckedEquals(emboss_reserved_local_other.q()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericRView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericRView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericRView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBits().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "q") {
+        if (!q().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_q().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          q().IsAggregate() || q().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("q: ");
+        q().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !q().IsAggregate() && !q().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# q: UNREADABLE\n");
+      }
+    }
+
+    if (has_q_plus_bit_size().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          q_plus_bit_size().IsAggregate() || q_plus_bit_size().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# q_plus_bit_size: ");
+        q_plus_bit_size().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# q_plus_bit_size: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ q() const;
+  ::emboss::support::Maybe<bool> has_q() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBitsView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView IntrinsicSizeInBits() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedVirtualQPlusBitSizeView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedVirtualQPlusBitSizeView(
+        const GenericRView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualQPlusBitSizeView() = delete;
+    EmbossReservedVirtualQPlusBitSizeView(const EmbossReservedVirtualQPlusBitSizeView &) = default;
+    EmbossReservedVirtualQPlusBitSizeView(EmbossReservedVirtualQPlusBitSizeView &&) = default;
+    EmbossReservedVirtualQPlusBitSizeView &operator=(const EmbossReservedVirtualQPlusBitSizeView &) =
+        default;
+    EmbossReservedVirtualQPlusBitSizeView &operator=(EmbossReservedVirtualQPlusBitSizeView &&) =
+        default;
+    ~EmbossReservedVirtualQPlusBitSizeView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_q_plus_bit_size().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.q();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)));
+
+      return emboss_reserved_local_subexpr_3;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericRView view_;
+  };
+  EmbossReservedVirtualQPlusBitSizeView q_plus_bit_size() const;
+  ::emboss::support::Maybe<bool> has_q_plus_bit_size() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBitsView() {}
+    EmbossReservedDollarVirtualMaxSizeInBitsView(const EmbossReservedDollarVirtualMaxSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView(EmbossReservedDollarVirtualMaxSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(const EmbossReservedDollarVirtualMaxSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBitsView &operator=(EmbossReservedDollarVirtualMaxSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBitsView MaxSizeInBits() {
+    return EmbossReservedDollarVirtualMaxSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBitsView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBitsView() {}
+    EmbossReservedDollarVirtualMinSizeInBitsView(const EmbossReservedDollarVirtualMinSizeInBitsView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView(EmbossReservedDollarVirtualMinSizeInBitsView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(const EmbossReservedDollarVirtualMinSizeInBitsView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBitsView &operator=(EmbossReservedDollarVirtualMinSizeInBitsView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBitsView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBitsView MinSizeInBits() {
+    return EmbossReservedDollarVirtualMinSizeInBitsView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericRView;
+};
+using RView =
+    GenericRView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using RWriter =
+    GenericRView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericRView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericRView<
+    GenericRView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericRView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeRView( T &&emboss_reserved_local_arg) {
+  return GenericRView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericRView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeRView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericRView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericRView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedRView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericRView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+}  // namespace UsesSize
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericUsesSizeView;
+
+template <class Storage>
+class GenericUsesSizeView final {
+ public:
+  GenericUsesSizeView() : backing_() {}
+  explicit GenericUsesSizeView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericUsesSizeView(
+      const GenericUsesSizeView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericUsesSizeView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericUsesSizeView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericUsesSizeView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericUsesSizeView<Storage> &operator=(
+      const GenericUsesSizeView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_r().Known()) return false;
+    if (has_r().ValueOrDefault() && !r().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_r_q_plus_byte_size().Known()) return false;
+    if (has_r_q_plus_byte_size().ValueOrDefault() && !r_q_plus_byte_size().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericUsesSizeView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_r().Known()) return false;
+    if (!emboss_reserved_local_other.has_r().Known()) return false;
+
+    if (emboss_reserved_local_other.has_r().ValueOrDefault() &&
+        !has_r().ValueOrDefault())
+      return false;
+    if (has_r().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_r().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_r().ValueOrDefault() &&
+        has_r().ValueOrDefault() &&
+        !r().Equals(emboss_reserved_local_other.r()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericUsesSizeView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_r().ValueOr(false) &&
+        !has_r().ValueOr(false))
+      return false;
+    if (has_r().ValueOr(false) &&
+        !emboss_reserved_local_other.has_r().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_r().ValueOr(false) &&
+        has_r().ValueOr(false) &&
+        !r().UncheckedEquals(emboss_reserved_local_other.r()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericUsesSizeView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericUsesSizeView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericUsesSizeView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "r") {
+        if (!r().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_r().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          r().IsAggregate() || r().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("r: ");
+        r().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !r().IsAggregate() && !r().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# r: UNREADABLE\n");
+      }
+    }
+
+    if (has_r_q_plus_byte_size().ValueOr(false) &&
+        emboss_reserved_local_field_options.comments()) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          r_q_plus_byte_size().IsAggregate() || r_q_plus_byte_size().Ok()) {
+        emboss_reserved_local_stream->Write(
+            emboss_reserved_local_field_options.current_indent());
+        emboss_reserved_local_stream->Write("# r_q_plus_byte_size: ");
+        r_q_plus_byte_size().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_stream->Write("\n");
+      } else {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# r_q_plus_byte_size: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::test::UsesSize::GenericRView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ r() const;
+  ::emboss::support::Maybe<bool> has_r() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedVirtualRQPlusByteSizeView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedVirtualRQPlusByteSizeView(
+        const GenericUsesSizeView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualRQPlusByteSizeView() = delete;
+    EmbossReservedVirtualRQPlusByteSizeView(const EmbossReservedVirtualRQPlusByteSizeView &) = default;
+    EmbossReservedVirtualRQPlusByteSizeView(EmbossReservedVirtualRQPlusByteSizeView &&) = default;
+    EmbossReservedVirtualRQPlusByteSizeView &operator=(const EmbossReservedVirtualRQPlusByteSizeView &) =
+        default;
+    EmbossReservedVirtualRQPlusByteSizeView &operator=(EmbossReservedVirtualRQPlusByteSizeView &&) =
+        default;
+    ~EmbossReservedVirtualRQPlusByteSizeView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_r_q_plus_byte_size().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.r().q();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)));
+
+      return emboss_reserved_local_subexpr_3;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericUsesSizeView view_;
+  };
+  EmbossReservedVirtualRQPlusByteSizeView r_q_plus_byte_size() const;
+  ::emboss::support::Maybe<bool> has_r_q_plus_byte_size() const;
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericUsesSizeView;
+};
+using UsesSizeView =
+    GenericUsesSizeView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using UsesSizeWriter =
+    GenericUsesSizeView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericUsesSizeView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericUsesSizeView<
+    GenericUsesSizeView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericUsesSizeView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeUsesSizeView( T &&emboss_reserved_local_arg) {
+  return GenericUsesSizeView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericUsesSizeView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeUsesSizeView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericUsesSizeView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericUsesSizeView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedUsesSizeView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericUsesSizeView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+namespace UsesExternalSize {
+
+}  // namespace UsesExternalSize
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericUsesExternalSizeView;
+
+template <class Storage>
+class GenericUsesExternalSizeView final {
+ public:
+  GenericUsesExternalSizeView() : backing_() {}
+  explicit GenericUsesExternalSizeView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericUsesExternalSizeView(
+      const GenericUsesExternalSizeView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericUsesExternalSizeView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericUsesExternalSizeView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericUsesExternalSizeView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericUsesExternalSizeView<Storage> &operator=(
+      const GenericUsesExternalSizeView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_y().Known()) return false;
+    if (has_y().ValueOrDefault() && !y().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericUsesExternalSizeView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (!has_y().Known()) return false;
+    if (!emboss_reserved_local_other.has_y().Known()) return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
+        !has_y().ValueOrDefault())
+      return false;
+    if (has_y().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_y().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
+        has_y().ValueOrDefault() &&
+        !y().Equals(emboss_reserved_local_other.y()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericUsesExternalSizeView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+
+
+    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
+        !has_y().ValueOr(false))
+      return false;
+    if (has_y().ValueOr(false) &&
+        !emboss_reserved_local_other.has_y().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
+        has_y().ValueOr(false) &&
+        !y().UncheckedEquals(emboss_reserved_local_other.y()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericUsesExternalSizeView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericUsesExternalSizeView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericUsesExternalSizeView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "y") {
+        if (!y().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_y().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          y().IsAggregate() || y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("y: ");
+        y().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !y().IsAggregate() && !y().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# y: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::test::GenericStructureWithConstantsView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  typename ::emboss::test::GenericStructureWithConstantsView<typename Storage::template OffsetStorageType</**/0, 4>>
+
+ y() const;
+  ::emboss::support::Maybe<bool> has_y() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericUsesExternalSizeView;
+};
+using UsesExternalSizeView =
+    GenericUsesExternalSizeView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using UsesExternalSizeWriter =
+    GenericUsesExternalSizeView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericUsesExternalSizeView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericUsesExternalSizeView<
+    GenericUsesExternalSizeView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericUsesExternalSizeView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeUsesExternalSizeView( T &&emboss_reserved_local_arg) {
+  return GenericUsesExternalSizeView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericUsesExternalSizeView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeUsesExternalSizeView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericUsesExternalSizeView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericUsesExternalSizeView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedUsesExternalSizeView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericUsesExternalSizeView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+
+
+
+
+
+
+
+namespace ImplicitWriteBack {
+
+}  // namespace ImplicitWriteBack
+
+
+template <class View>
+struct EmbossReservedInternalIsGenericImplicitWriteBackView;
+
+template <class Storage>
+class GenericImplicitWriteBackView final {
+ public:
+  GenericImplicitWriteBackView() : backing_() {}
+  explicit GenericImplicitWriteBackView(
+       Storage emboss_reserved_local_bytes)
+      : backing_(emboss_reserved_local_bytes) 
+         {}
+
+  template <typename OtherStorage>
+  GenericImplicitWriteBackView(
+      const GenericImplicitWriteBackView<OtherStorage> &emboss_reserved_local_other)
+      : backing_{emboss_reserved_local_other.BackingStorage()}
+         {}
+
+  template <typename Arg,
+            typename = typename ::std::enable_if<
+                !EmbossReservedInternalIsGenericImplicitWriteBackView<
+                    typename ::std::remove_cv<typename ::std::remove_reference<
+                        Arg>::type>::type>::value>::type>
+  explicit GenericImplicitWriteBackView(
+       Arg &&emboss_reserved_local_arg)
+      : backing_(::std::forward<Arg>(
+            emboss_reserved_local_arg)) 
+         {}
+  template <typename Arg0, typename Arg1, typename... Args>
+  explicit GenericImplicitWriteBackView(
+       Arg0 &&emboss_reserved_local_arg0,
+      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
+      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
+                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
+                 ::std::forward<Args>(
+                     emboss_reserved_local_args)...) 
+         {}
+
+  template <typename OtherStorage>
+  GenericImplicitWriteBackView<Storage> &operator=(
+      const GenericImplicitWriteBackView<OtherStorage> &emboss_reserved_local_other) {
+    backing_ = emboss_reserved_local_other.BackingStorage();
+    return *this;
+  }
+
+  
+
+  bool Ok() const {
+    if (!IsComplete()) return false;
+
+    if (!has_x().Known()) return false;
+    if (has_x().ValueOrDefault() && !x().Ok()) return false;
+
+
+    if (!has_x_plus_ten().Known()) return false;
+    if (has_x_plus_ten().ValueOrDefault() && !x_plus_ten().Ok()) return false;
+
+
+    if (!has_ten_plus_x().Known()) return false;
+    if (has_ten_plus_x().ValueOrDefault() && !ten_plus_x().Ok()) return false;
+
+
+    if (!has_x_minus_ten().Known()) return false;
+    if (has_x_minus_ten().ValueOrDefault() && !x_minus_ten().Ok()) return false;
+
+
+    if (!has_ten_minus_x().Known()) return false;
+    if (has_ten_minus_x().ValueOrDefault() && !ten_minus_x().Ok()) return false;
+
+
+    if (!has_ten_minus_x_plus_ten().Known()) return false;
+    if (has_ten_minus_x_plus_ten().ValueOrDefault() && !ten_minus_x_plus_ten().Ok()) return false;
+
+
+    if (!has_IntrinsicSizeInBytes().Known()) return false;
+    if (has_IntrinsicSizeInBytes().ValueOrDefault() && !IntrinsicSizeInBytes().Ok()) return false;
+
+
+    if (!has_MaxSizeInBytes().Known()) return false;
+    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) return false;
+
+
+    if (!has_MinSizeInBytes().Known()) return false;
+    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) return false;
+
+
+
+    return true;
+  }
+  Storage BackingStorage() const { return backing_; }
+  bool IsComplete() const {
+    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
+           backing_.SizeInBytes() >=
+               static_cast</**/ ::std::size_t>(
+                   IntrinsicSizeInBytes().UncheckedRead());
+  }
+  static constexpr ::std::size_t SizeInBytes() {
+    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
+  }
+  static constexpr bool SizeIsKnown() {
+    return IntrinsicSizeInBytes().Ok();
+  }
+
+
+  template <typename OtherStorage>
+  bool Equals(
+      GenericImplicitWriteBackView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (!has_x().Known()) return false;
+    if (!emboss_reserved_local_other.has_x().Known()) return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        !has_x().ValueOrDefault())
+      return false;
+    if (has_x().ValueOrDefault() &&
+        !emboss_reserved_local_other.has_x().ValueOrDefault())
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
+        has_x().ValueOrDefault() &&
+        !x().Equals(emboss_reserved_local_other.x()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  bool UncheckedEquals(
+      GenericImplicitWriteBackView<OtherStorage> emboss_reserved_local_other) const {
+    
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        !has_x().ValueOr(false))
+      return false;
+    if (has_x().ValueOr(false) &&
+        !emboss_reserved_local_other.has_x().ValueOr(false))
+      return false;
+
+    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
+        has_x().ValueOr(false) &&
+        !x().UncheckedEquals(emboss_reserved_local_other.x()))
+      return false;
+
+ return true;
+  }
+  template <typename OtherStorage>
+  void UncheckedCopyFrom(
+      GenericImplicitWriteBackView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.UncheckedCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
+  }
+
+  template <typename OtherStorage>
+  void CopyFrom(
+      GenericImplicitWriteBackView<OtherStorage> emboss_reserved_local_other) const {
+    backing_.CopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+  template <typename OtherStorage>
+  bool TryToCopyFrom(
+      GenericImplicitWriteBackView<OtherStorage> emboss_reserved_local_other) const {
+      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
+        emboss_reserved_local_other.BackingStorage(),
+        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
+  }
+
+  template <class Stream>
+  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
+    ::std::string emboss_reserved_local_brace;
+    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                      &emboss_reserved_local_brace))
+      return false;
+    if (emboss_reserved_local_brace != "{") return false;
+    for (;;) {
+      ::std::string emboss_reserved_local_name;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_name))
+        return false;
+      if (emboss_reserved_local_name == ",")
+        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                          &emboss_reserved_local_name))
+          return false;
+      if (emboss_reserved_local_name == "}") return true;
+      ::std::string emboss_reserved_local_colon;
+      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
+                                        &emboss_reserved_local_colon))
+        return false;
+      if (emboss_reserved_local_colon != ":") return false;
+      if (emboss_reserved_local_name == "x") {
+        if (!x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "x_plus_ten") {
+        if (!x_plus_ten().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "ten_plus_x") {
+        if (!ten_plus_x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "x_minus_ten") {
+        if (!x_minus_ten().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "ten_minus_x") {
+        if (!ten_minus_x().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      if (emboss_reserved_local_name == "ten_minus_x_plus_ten") {
+        if (!ten_minus_x_plus_ten().UpdateFromTextStream(
+                emboss_reserved_local_stream)) {
+          return false;
+        }
+        continue;
+      }
+
+      return false;
+    }
+  }
+
+  template <class Stream>
+  void WriteToTextStream(
+      Stream *emboss_reserved_local_stream,
+      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
+    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
+        emboss_reserved_local_options.PlusOneIndent();
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write("{\n");
+    } else {
+      emboss_reserved_local_stream->Write("{");
+    }
+    bool emboss_reserved_local_wrote_field = false;
+    if (has_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x().IsAggregate() || x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x: ");
+        x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x().IsAggregate() && !x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x: UNREADABLE\n");
+      }
+    }
+
+    if (has_x_plus_ten().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x_plus_ten().IsAggregate() || x_plus_ten().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x_plus_ten: ");
+        x_plus_ten().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x_plus_ten().IsAggregate() && !x_plus_ten().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x_plus_ten: UNREADABLE\n");
+      }
+    }
+
+    if (has_ten_plus_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          ten_plus_x().IsAggregate() || ten_plus_x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("ten_plus_x: ");
+        ten_plus_x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !ten_plus_x().IsAggregate() && !ten_plus_x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# ten_plus_x: UNREADABLE\n");
+      }
+    }
+
+    if (has_x_minus_ten().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          x_minus_ten().IsAggregate() || x_minus_ten().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("x_minus_ten: ");
+        x_minus_ten().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !x_minus_ten().IsAggregate() && !x_minus_ten().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# x_minus_ten: UNREADABLE\n");
+      }
+    }
+
+    if (has_ten_minus_x().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          ten_minus_x().IsAggregate() || ten_minus_x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("ten_minus_x: ");
+        ten_minus_x().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !ten_minus_x().IsAggregate() && !ten_minus_x().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# ten_minus_x: UNREADABLE\n");
+      }
+    }
+
+    if (has_ten_minus_x_plus_ten().ValueOr(false)) {
+      if (!emboss_reserved_local_field_options.allow_partial_output() ||
+          ten_minus_x_plus_ten().IsAggregate() || ten_minus_x_plus_ten().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        } else {
+          if (emboss_reserved_local_wrote_field) {
+            emboss_reserved_local_stream->Write(",");
+          }
+          emboss_reserved_local_stream->Write(" ");
+        }
+        emboss_reserved_local_stream->Write("ten_minus_x_plus_ten: ");
+        ten_minus_x_plus_ten().WriteToTextStream(emboss_reserved_local_stream,
+                                           emboss_reserved_local_field_options);
+        emboss_reserved_local_wrote_field = true;
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write("\n");
+        }
+      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
+                 emboss_reserved_local_field_options.comments() &&
+                 !ten_minus_x_plus_ten().IsAggregate() && !ten_minus_x_plus_ten().Ok()) {
+        if (emboss_reserved_local_field_options.multiline()) {
+          emboss_reserved_local_stream->Write(
+              emboss_reserved_local_field_options.current_indent());
+        }
+        emboss_reserved_local_stream->Write("# ten_minus_x_plus_ten: UNREADABLE\n");
+      }
+    }
+
+    (void)emboss_reserved_local_wrote_field;
+    if (emboss_reserved_local_options.multiline()) {
+      emboss_reserved_local_stream->Write(
+          emboss_reserved_local_options.current_indent());
+      emboss_reserved_local_stream->Write("}");
+    } else {
+      emboss_reserved_local_stream->Write(" }");
+    }
+  }
+
+
+
+  static constexpr bool IsAggregate() { return true; }
+
+ public:
+  typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ x() const;
+  ::emboss::support::Maybe<bool> has_x() const;
+
+ public:
+  class EmbossReservedVirtualXPlusTenView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedVirtualXPlusTenView(
+        const GenericImplicitWriteBackView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualXPlusTenView() = delete;
+    EmbossReservedVirtualXPlusTenView(const EmbossReservedVirtualXPlusTenView &) = default;
+    EmbossReservedVirtualXPlusTenView(EmbossReservedVirtualXPlusTenView &&) = default;
+    EmbossReservedVirtualXPlusTenView &operator=(const EmbossReservedVirtualXPlusTenView &) =
+        default;
+    EmbossReservedVirtualXPlusTenView &operator=(EmbossReservedVirtualXPlusTenView &&) =
+        default;
+    ~EmbossReservedVirtualXPlusTenView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_x_plus_ten().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+    bool TryToWrite(::std::int32_t emboss_reserved_local_value) {
+      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)));
+      if (!CouldWriteValue(emboss_reserved_local_value)) return false;
+      return view_.x().TryToWrite(
+          emboss_reserved_local_maybe_new_value.ValueOrDefault());
+    }
+    void Write(::std::int32_t emboss_reserved_local_value) {
+      const bool result = TryToWrite(emboss_reserved_local_value);
+      (void)result;
+      EMBOSS_CHECK(result);
+    }
+    void UncheckedWrite(::std::int32_t emboss_reserved_local_value) {
+      view_.x().UncheckedWrite((::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)))).ValueOrDefault());
+    }
+    bool CouldWriteValue(::std::int32_t emboss_reserved_local_value) {
+      if (!ValueIsOk(emboss_reserved_local_value)) return false;
+      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)));
+      if (!emboss_reserved_local_maybe_new_value.Known()) return false;
+      return view_.x().CouldWriteValue(
+          emboss_reserved_local_maybe_new_value.ValueOrDefault());
+    }
+    template <class Stream>
+    bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) {
+      return ::emboss::support::ReadIntegerFromTextStream(
+          this, emboss_reserved_local_stream);
+    }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)));
+
+      return emboss_reserved_local_subexpr_3;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericImplicitWriteBackView view_;
+  };
+  EmbossReservedVirtualXPlusTenView x_plus_ten() const;
+  ::emboss::support::Maybe<bool> has_x_plus_ten() const;
+
+ public:
+  class EmbossReservedVirtualTenPlusXView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedVirtualTenPlusXView(
+        const GenericImplicitWriteBackView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualTenPlusXView() = delete;
+    EmbossReservedVirtualTenPlusXView(const EmbossReservedVirtualTenPlusXView &) = default;
+    EmbossReservedVirtualTenPlusXView(EmbossReservedVirtualTenPlusXView &&) = default;
+    EmbossReservedVirtualTenPlusXView &operator=(const EmbossReservedVirtualTenPlusXView &) =
+        default;
+    EmbossReservedVirtualTenPlusXView &operator=(EmbossReservedVirtualTenPlusXView &&) =
+        default;
+    ~EmbossReservedVirtualTenPlusXView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_ten_plus_x().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+    bool TryToWrite(::std::int32_t emboss_reserved_local_value) {
+      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)));
+      if (!CouldWriteValue(emboss_reserved_local_value)) return false;
+      return view_.x().TryToWrite(
+          emboss_reserved_local_maybe_new_value.ValueOrDefault());
+    }
+    void Write(::std::int32_t emboss_reserved_local_value) {
+      const bool result = TryToWrite(emboss_reserved_local_value);
+      (void)result;
+      EMBOSS_CHECK(result);
+    }
+    void UncheckedWrite(::std::int32_t emboss_reserved_local_value) {
+      view_.x().UncheckedWrite((::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)))).ValueOrDefault());
+    }
+    bool CouldWriteValue(::std::int32_t emboss_reserved_local_value) {
+      if (!ValueIsOk(emboss_reserved_local_value)) return false;
+      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)));
+      if (!emboss_reserved_local_maybe_new_value.Known()) return false;
+      return view_.x().CouldWriteValue(
+          emboss_reserved_local_maybe_new_value.ValueOrDefault());
+    }
+    template <class Stream>
+    bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) {
+      return ::emboss::support::ReadIntegerFromTextStream(
+          this, emboss_reserved_local_stream);
+    }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)), emboss_reserved_local_subexpr_2);
+
+      return emboss_reserved_local_subexpr_3;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericImplicitWriteBackView view_;
+  };
+  EmbossReservedVirtualTenPlusXView ten_plus_x() const;
+  ::emboss::support::Maybe<bool> has_ten_plus_x() const;
+
+ public:
+  class EmbossReservedVirtualXMinusTenView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedVirtualXMinusTenView(
+        const GenericImplicitWriteBackView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualXMinusTenView() = delete;
+    EmbossReservedVirtualXMinusTenView(const EmbossReservedVirtualXMinusTenView &) = default;
+    EmbossReservedVirtualXMinusTenView(EmbossReservedVirtualXMinusTenView &&) = default;
+    EmbossReservedVirtualXMinusTenView &operator=(const EmbossReservedVirtualXMinusTenView &) =
+        default;
+    EmbossReservedVirtualXMinusTenView &operator=(EmbossReservedVirtualXMinusTenView &&) =
+        default;
+    ~EmbossReservedVirtualXMinusTenView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_x_minus_ten().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+    bool TryToWrite(::std::int32_t emboss_reserved_local_value) {
+      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)));
+      if (!CouldWriteValue(emboss_reserved_local_value)) return false;
+      return view_.x().TryToWrite(
+          emboss_reserved_local_maybe_new_value.ValueOrDefault());
+    }
+    void Write(::std::int32_t emboss_reserved_local_value) {
+      const bool result = TryToWrite(emboss_reserved_local_value);
+      (void)result;
+      EMBOSS_CHECK(result);
+    }
+    void UncheckedWrite(::std::int32_t emboss_reserved_local_value) {
+      view_.x().UncheckedWrite((::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)))).ValueOrDefault());
+    }
+    bool CouldWriteValue(::std::int32_t emboss_reserved_local_value) {
+      if (!ValueIsOk(emboss_reserved_local_value)) return false;
+      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)));
+      if (!emboss_reserved_local_maybe_new_value.Known()) return false;
+      return view_.x().CouldWriteValue(
+          emboss_reserved_local_maybe_new_value.ValueOrDefault());
+    }
+    template <class Stream>
+    bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) {
+      return ::emboss::support::ReadIntegerFromTextStream(
+          this, emboss_reserved_local_stream);
+    }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_2, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)));
+
+      return emboss_reserved_local_subexpr_3;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericImplicitWriteBackView view_;
+  };
+  EmbossReservedVirtualXMinusTenView x_minus_ten() const;
+  ::emboss::support::Maybe<bool> has_x_minus_ten() const;
+
+ public:
+  class EmbossReservedVirtualTenMinusXView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedVirtualTenMinusXView(
+        const GenericImplicitWriteBackView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualTenMinusXView() = delete;
+    EmbossReservedVirtualTenMinusXView(const EmbossReservedVirtualTenMinusXView &) = default;
+    EmbossReservedVirtualTenMinusXView(EmbossReservedVirtualTenMinusXView &&) = default;
+    EmbossReservedVirtualTenMinusXView &operator=(const EmbossReservedVirtualTenMinusXView &) =
+        default;
+    EmbossReservedVirtualTenMinusXView &operator=(EmbossReservedVirtualTenMinusXView &&) =
+        default;
+    ~EmbossReservedVirtualTenMinusXView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_ten_minus_x().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+    bool TryToWrite(::std::int32_t emboss_reserved_local_value) {
+      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)), ::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value));
+      if (!CouldWriteValue(emboss_reserved_local_value)) return false;
+      return view_.x().TryToWrite(
+          emboss_reserved_local_maybe_new_value.ValueOrDefault());
+    }
+    void Write(::std::int32_t emboss_reserved_local_value) {
+      const bool result = TryToWrite(emboss_reserved_local_value);
+      (void)result;
+      EMBOSS_CHECK(result);
+    }
+    void UncheckedWrite(::std::int32_t emboss_reserved_local_value) {
+      view_.x().UncheckedWrite((::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)), ::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value))).ValueOrDefault());
+    }
+    bool CouldWriteValue(::std::int32_t emboss_reserved_local_value) {
+      if (!ValueIsOk(emboss_reserved_local_value)) return false;
+      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)), ::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value));
+      if (!emboss_reserved_local_maybe_new_value.Known()) return false;
+      return view_.x().CouldWriteValue(
+          emboss_reserved_local_maybe_new_value.ValueOrDefault());
+    }
+    template <class Stream>
+    bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) {
+      return ::emboss::support::ReadIntegerFromTextStream(
+          this, emboss_reserved_local_stream);
+    }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)), emboss_reserved_local_subexpr_2);
+
+      return emboss_reserved_local_subexpr_3;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericImplicitWriteBackView view_;
+  };
+  EmbossReservedVirtualTenMinusXView ten_minus_x() const;
+  ::emboss::support::Maybe<bool> has_ten_minus_x() const;
+
+ public:
+  class EmbossReservedVirtualTenMinusXPlusTenView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    explicit EmbossReservedVirtualTenMinusXPlusTenView(
+        const GenericImplicitWriteBackView &emboss_reserved_local_view)
+        : view_(emboss_reserved_local_view) {}
+    EmbossReservedVirtualTenMinusXPlusTenView() = delete;
+    EmbossReservedVirtualTenMinusXPlusTenView(const EmbossReservedVirtualTenMinusXPlusTenView &) = default;
+    EmbossReservedVirtualTenMinusXPlusTenView(EmbossReservedVirtualTenMinusXPlusTenView &&) = default;
+    EmbossReservedVirtualTenMinusXPlusTenView &operator=(const EmbossReservedVirtualTenMinusXPlusTenView &) =
+        default;
+    EmbossReservedVirtualTenMinusXPlusTenView &operator=(EmbossReservedVirtualTenMinusXPlusTenView &&) =
+        default;
+    ~EmbossReservedVirtualTenMinusXPlusTenView() = default;
+
+    ::std::int32_t Read() const {
+      EMBOSS_CHECK(view_.has_ten_minus_x_plus_ten().ValueOr(false));
+      auto emboss_reserved_local_value = MaybeRead();
+      EMBOSS_CHECK(emboss_reserved_local_value.Known());
+      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
+      return emboss_reserved_local_value.ValueOrDefault();
+    }
+    ::std::int32_t UncheckedRead() const {
+      return MaybeRead().ValueOrDefault();
+    }
+    bool Ok() const {
+      auto emboss_reserved_local_value = MaybeRead();
+      return emboss_reserved_local_value.Known() &&
+             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
+    }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+
+    bool TryToWrite(::std::int32_t emboss_reserved_local_value) {
+      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)), ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL))));
+      if (!CouldWriteValue(emboss_reserved_local_value)) return false;
+      return view_.x().TryToWrite(
+          emboss_reserved_local_maybe_new_value.ValueOrDefault());
+    }
+    void Write(::std::int32_t emboss_reserved_local_value) {
+      const bool result = TryToWrite(emboss_reserved_local_value);
+      (void)result;
+      EMBOSS_CHECK(result);
+    }
+    void UncheckedWrite(::std::int32_t emboss_reserved_local_value) {
+      view_.x().UncheckedWrite((::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)), ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL))))).ValueOrDefault());
+    }
+    bool CouldWriteValue(::std::int32_t emboss_reserved_local_value) {
+      if (!ValueIsOk(emboss_reserved_local_value)) return false;
+      const auto emboss_reserved_local_maybe_new_value = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)), ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/decltype(emboss_reserved_local_value)>(emboss_reserved_local_value), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL))));
+      if (!emboss_reserved_local_maybe_new_value.Known()) return false;
+      return view_.x().CouldWriteValue(
+          emboss_reserved_local_maybe_new_value.ValueOrDefault());
+    }
+    template <class Stream>
+    bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) {
+      return ::emboss::support::ReadIntegerFromTextStream(
+          this, emboss_reserved_local_stream);
+    }
+
+
+
+   private:
+    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
+      const auto emboss_reserved_local_subexpr_1 = view_.x();
+      const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>());
+      const auto emboss_reserved_local_subexpr_3 = ::emboss::support::Difference</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)), emboss_reserved_local_subexpr_2);
+      const auto emboss_reserved_local_subexpr_4 = ::emboss::support::Sum</**/::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t>(emboss_reserved_local_subexpr_3, ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)));
+
+      return emboss_reserved_local_subexpr_4;
+    }
+
+    static constexpr bool ValueIsOk(
+        ::std::int32_t emboss_reserved_local_value) {
+      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
+             ::emboss::support::Maybe<bool>(true).ValueOr(false);
+    }
+
+    const GenericImplicitWriteBackView view_;
+  };
+  EmbossReservedVirtualTenMinusXPlusTenView ten_minus_x_plus_ten() const;
+  ::emboss::support::Maybe<bool> has_ten_minus_x_plus_ten() const;
+
+ public:
+  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {}
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(const EmbossReservedDollarVirtualIntrinsicSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualIntrinsicSizeInBytesView &operator=(EmbossReservedDollarVirtualIntrinsicSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() {
+    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {}
+    EmbossReservedDollarVirtualMaxSizeInBytesView(const EmbossReservedDollarVirtualMaxSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView(EmbossReservedDollarVirtualMaxSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(const EmbossReservedDollarVirtualMaxSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMaxSizeInBytesView &operator=(EmbossReservedDollarVirtualMaxSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView MaxSizeInBytes() {
+    return EmbossReservedDollarVirtualMaxSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+ public:
+  class EmbossReservedDollarVirtualMinSizeInBytesView final {
+   public:
+    using ValueType = ::std::int32_t;
+
+    constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {}
+    EmbossReservedDollarVirtualMinSizeInBytesView(const EmbossReservedDollarVirtualMinSizeInBytesView &) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView(EmbossReservedDollarVirtualMinSizeInBytesView &&) = default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(const EmbossReservedDollarVirtualMinSizeInBytesView &) =
+        default;
+    EmbossReservedDollarVirtualMinSizeInBytesView &operator=(EmbossReservedDollarVirtualMinSizeInBytesView &&) =
+        default;
+    ~EmbossReservedDollarVirtualMinSizeInBytesView() = default;
+
+    static constexpr ::std::int32_t Read();
+    static constexpr ::std::int32_t UncheckedRead();
+    static constexpr bool Ok() { return true; }
+    template <class Stream>
+    void WriteToTextStream(Stream *emboss_reserved_local_stream,
+                           const ::emboss::TextOutputOptions
+                               &emboss_reserved_local_options) const {
+      ::emboss::support::WriteIntegerViewToTextStream(
+          this, emboss_reserved_local_stream, emboss_reserved_local_options);
+    }
+
+    static constexpr bool IsAggregate() { return false; }
+  };
+
+  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView MinSizeInBytes() {
+    return EmbossReservedDollarVirtualMinSizeInBytesView();
+  }
+  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
+    return ::emboss::support::Maybe<bool>(true);
+  }
+
+
+
+ private:
+  Storage backing_;
+  
+  
+
+  template <class OtherStorage>
+  friend class GenericImplicitWriteBackView;
+};
+using ImplicitWriteBackView =
+    GenericImplicitWriteBackView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
+using ImplicitWriteBackWriter =
+    GenericImplicitWriteBackView</**/ ::emboss::support::ReadWriteContiguousBuffer>;
+
+template <class View>
+struct EmbossReservedInternalIsGenericImplicitWriteBackView {
+  static constexpr const bool value = false;
+};
+
+template <class Storage>
+struct EmbossReservedInternalIsGenericImplicitWriteBackView<
+    GenericImplicitWriteBackView<Storage>> {
+  static constexpr const bool value = true;
+};
+
+template <typename T>
+inline GenericImplicitWriteBackView<
+    /**/ ::emboss::support::ContiguousBuffer<
+        typename ::std::remove_reference<
+            decltype(*::std::declval<T>()->data())>::type,
+        1, 0>>
+MakeImplicitWriteBackView( T &&emboss_reserved_local_arg) {
+  return GenericImplicitWriteBackView<
+      /**/ ::emboss::support::ContiguousBuffer<
+          typename ::std::remove_reference<decltype(
+              *::std::declval<T>()->data())>::type,
+          1, 0>>(
+       ::std::forward<T>(emboss_reserved_local_arg));
+}
+
+template <typename T>
+inline GenericImplicitWriteBackView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
+MakeImplicitWriteBackView( T *emboss_reserved_local_data,
+                 ::std::size_t emboss_reserved_local_size) {
+  return GenericImplicitWriteBackView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+template <typename T, ::std::size_t kAlignment>
+inline GenericImplicitWriteBackView<
+    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
+MakeAlignedImplicitWriteBackView(
+     T *emboss_reserved_local_data,
+    ::std::size_t emboss_reserved_local_size) {
+  return GenericImplicitWriteBackView<
+      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
+       emboss_reserved_local_data,
+      emboss_reserved_local_size);
+}
+
+namespace StructureWithConstants {
+
+}  // namespace StructureWithConstants
+
+
+namespace StructureWithConstants {
+inline constexpr ::std::int32_t ten() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)).ValueOrDefault();
+}
+}  // namespace StructureWithConstants
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithConstantsView<Storage>::EmbossReservedVirtualTenView::Read() {
+  return StructureWithConstants::ten();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithConstantsView<
+    Storage>::EmbossReservedVirtualTenView::UncheckedRead() {
+  return StructureWithConstants::ten();
+}
+
+namespace StructureWithConstants {
+inline constexpr ::std::int32_t twenty() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(20LL)).ValueOrDefault();
+}
+}  // namespace StructureWithConstants
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithConstantsView<Storage>::EmbossReservedVirtualTwentyView::Read() {
+  return StructureWithConstants::twenty();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithConstantsView<
+    Storage>::EmbossReservedVirtualTwentyView::UncheckedRead() {
+  return StructureWithConstants::twenty();
+}
+
+namespace StructureWithConstants {
+inline constexpr ::std::uint32_t four_billion() {
+  return ::emboss::support::Maybe</**/::std::uint32_t>(static_cast</**/::std::uint32_t>(4000000000ULL)).ValueOrDefault();
+}
+}  // namespace StructureWithConstants
+
+template <class Storage>
+inline constexpr ::std::uint32_t
+GenericStructureWithConstantsView<Storage>::EmbossReservedVirtualFourBillionView::Read() {
+  return StructureWithConstants::four_billion();
+}
+
+template <class Storage>
+inline constexpr ::std::uint32_t
+GenericStructureWithConstantsView<
+    Storage>::EmbossReservedVirtualFourBillionView::UncheckedRead() {
+  return StructureWithConstants::four_billion();
+}
+
+namespace StructureWithConstants {
+inline constexpr ::std::int64_t ten_billion() {
+  return ::emboss::support::Maybe</**/::std::int64_t>(static_cast</**/::std::int64_t>(10000000000LL)).ValueOrDefault();
+}
+}  // namespace StructureWithConstants
+
+template <class Storage>
+inline constexpr ::std::int64_t
+GenericStructureWithConstantsView<Storage>::EmbossReservedVirtualTenBillionView::Read() {
+  return StructureWithConstants::ten_billion();
+}
+
+template <class Storage>
+inline constexpr ::std::int64_t
+GenericStructureWithConstantsView<
+    Storage>::EmbossReservedVirtualTenBillionView::UncheckedRead() {
+  return StructureWithConstants::ten_billion();
+}
+
+namespace StructureWithConstants {
+inline constexpr ::std::int64_t minus_ten_billion() {
+  return ::emboss::support::Maybe</**/::std::int64_t>(static_cast</**/::std::int64_t>(-10000000000LL)).ValueOrDefault();
+}
+}  // namespace StructureWithConstants
+
+template <class Storage>
+inline constexpr ::std::int64_t
+GenericStructureWithConstantsView<Storage>::EmbossReservedVirtualMinusTenBillionView::Read() {
+  return StructureWithConstants::minus_ten_billion();
+}
+
+template <class Storage>
+inline constexpr ::std::int64_t
+GenericStructureWithConstantsView<
+    Storage>::EmbossReservedVirtualMinusTenBillionView::UncheckedRead() {
+  return StructureWithConstants::minus_ten_billion();
+}
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ GenericStructureWithConstantsView<Storage>::value()
+    const {
+
+  if ( has_value().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithConstantsView<Storage>::has_value() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithConstantsView<Storage>::has_alias_of_value() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithConstantsView<Storage>::has_alias_of_alias_of_value() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace StructureWithConstants {
+inline constexpr ::std::int32_t alias_of_ten() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)).ValueOrDefault();
+}
+}  // namespace StructureWithConstants
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithConstantsView<Storage>::EmbossReservedVirtualAliasOfTenView::Read() {
+  return StructureWithConstants::alias_of_ten();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithConstantsView<
+    Storage>::EmbossReservedVirtualAliasOfTenView::UncheckedRead() {
+  return StructureWithConstants::alias_of_ten();
+}
+
+namespace StructureWithConstants {
+inline constexpr ::std::int32_t alias_of_alias_of_ten() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)).ValueOrDefault();
+}
+}  // namespace StructureWithConstants
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithConstantsView<Storage>::EmbossReservedVirtualAliasOfAliasOfTenView::Read() {
+  return StructureWithConstants::alias_of_alias_of_ten();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithConstantsView<
+    Storage>::EmbossReservedVirtualAliasOfAliasOfTenView::UncheckedRead() {
+  return StructureWithConstants::alias_of_alias_of_ten();
+}
+
+namespace StructureWithConstants {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace StructureWithConstants
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithConstantsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return StructureWithConstants::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithConstantsView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return StructureWithConstants::IntrinsicSizeInBytes();
+}
+
+namespace StructureWithConstants {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace StructureWithConstants
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithConstantsView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return StructureWithConstants::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithConstantsView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return StructureWithConstants::MaxSizeInBytes();
+}
+
+namespace StructureWithConstants {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace StructureWithConstants
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithConstantsView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return StructureWithConstants::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithConstantsView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return StructureWithConstants::MinSizeInBytes();
+}
+namespace StructureWithComputedValues {
+
+}  // namespace StructureWithComputedValues
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ GenericStructureWithComputedValuesView<Storage>::value()
+    const {
+
+  if ( has_value().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithComputedValuesView<Storage>::has_value() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericStructureWithComputedValuesView<Storage>::EmbossReservedVirtualDoubledView
+GenericStructureWithComputedValuesView<Storage>::doubled() const {
+  return
+      typename GenericStructureWithComputedValuesView<Storage>::EmbossReservedVirtualDoubledView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithComputedValuesView<Storage>::has_doubled() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericStructureWithComputedValuesView<Storage>::EmbossReservedVirtualPlusTenView
+GenericStructureWithComputedValuesView<Storage>::plus_ten() const {
+  return
+      typename GenericStructureWithComputedValuesView<Storage>::EmbossReservedVirtualPlusTenView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithComputedValuesView<Storage>::has_plus_ten() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+ GenericStructureWithComputedValuesView<Storage>::value2()
+    const {
+
+  if ( has_value2().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   4>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::IntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithComputedValuesView<Storage>::has_value2() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericStructureWithComputedValuesView<Storage>::EmbossReservedVirtualSignedDoubledView
+GenericStructureWithComputedValuesView<Storage>::signed_doubled() const {
+  return
+      typename GenericStructureWithComputedValuesView<Storage>::EmbossReservedVirtualSignedDoubledView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithComputedValuesView<Storage>::has_signed_doubled() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericStructureWithComputedValuesView<Storage>::EmbossReservedVirtualSignedPlusTenView
+GenericStructureWithComputedValuesView<Storage>::signed_plus_ten() const {
+  return
+      typename GenericStructureWithComputedValuesView<Storage>::EmbossReservedVirtualSignedPlusTenView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithComputedValuesView<Storage>::has_signed_plus_ten() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericStructureWithComputedValuesView<Storage>::EmbossReservedVirtualProductView
+GenericStructureWithComputedValuesView<Storage>::product() const {
+  return
+      typename GenericStructureWithComputedValuesView<Storage>::EmbossReservedVirtualProductView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithComputedValuesView<Storage>::has_product() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace StructureWithComputedValues {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace StructureWithComputedValues
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithComputedValuesView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return StructureWithComputedValues::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithComputedValuesView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return StructureWithComputedValues::IntrinsicSizeInBytes();
+}
+
+namespace StructureWithComputedValues {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace StructureWithComputedValues
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithComputedValuesView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return StructureWithComputedValues::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithComputedValuesView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return StructureWithComputedValues::MaxSizeInBytes();
+}
+
+namespace StructureWithComputedValues {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace StructureWithComputedValues
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithComputedValuesView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return StructureWithComputedValues::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithComputedValuesView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return StructureWithComputedValues::MinSizeInBytes();
+}
+namespace StructureWithConditionalValue {
+
+}  // namespace StructureWithConditionalValue
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ GenericStructureWithConditionalValueView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithConditionalValueView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericStructureWithConditionalValueView<Storage>::EmbossReservedVirtualTwoXView
+GenericStructureWithConditionalValueView<Storage>::two_x() const {
+  return
+      typename GenericStructureWithConditionalValueView<Storage>::EmbossReservedVirtualTwoXView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithConditionalValueView<Storage>::has_two_x() const {
+  return ::emboss::support::LessThan</**/::std::uint32_t, bool, ::std::uint32_t, ::std::uint32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::uint32_t>(static_cast</**/::std::uint32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::uint32_t>()), ::emboss::support::Maybe</**/::std::uint32_t>(static_cast</**/::std::uint32_t>(2147483648ULL)));
+}
+
+
+template <class Storage>
+inline typename GenericStructureWithConditionalValueView<Storage>::EmbossReservedVirtualXPlusOneView
+GenericStructureWithConditionalValueView<Storage>::x_plus_one() const {
+  return
+      typename GenericStructureWithConditionalValueView<Storage>::EmbossReservedVirtualXPlusOneView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithConditionalValueView<Storage>::has_x_plus_one() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace StructureWithConditionalValue {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace StructureWithConditionalValue
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithConditionalValueView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return StructureWithConditionalValue::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithConditionalValueView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return StructureWithConditionalValue::IntrinsicSizeInBytes();
+}
+
+namespace StructureWithConditionalValue {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace StructureWithConditionalValue
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithConditionalValueView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return StructureWithConditionalValue::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithConditionalValueView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return StructureWithConditionalValue::MaxSizeInBytes();
+}
+
+namespace StructureWithConditionalValue {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace StructureWithConditionalValue
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithConditionalValueView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return StructureWithConditionalValue::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithConditionalValueView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return StructureWithConditionalValue::MinSizeInBytes();
+}
+namespace StructureWithValueInCondition {
+
+}  // namespace StructureWithValueInCondition
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ GenericStructureWithValueInConditionView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithValueInConditionView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericStructureWithValueInConditionView<Storage>::EmbossReservedVirtualTwoXView
+GenericStructureWithValueInConditionView<Storage>::two_x() const {
+  return
+      typename GenericStructureWithValueInConditionView<Storage>::EmbossReservedVirtualTwoXView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithValueInConditionView<Storage>::has_two_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+ GenericStructureWithValueInConditionView<Storage>::if_two_x_lt_100()
+    const {
+
+  if ( has_if_two_x_lt_100().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   4>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithValueInConditionView<Storage>::has_if_two_x_lt_100() const {
+  return ::emboss::support::LessThan</**/::std::int64_t, bool, ::std::int64_t, ::std::int32_t>((two_x().Ok()    ? ::emboss::support::Maybe</**/::std::int64_t>(static_cast</**/::std::int64_t>(two_x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int64_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(100LL)));
+}
+
+
+template <class Storage>
+inline typename GenericStructureWithValueInConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericStructureWithValueInConditionView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericStructureWithValueInConditionView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithValueInConditionView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace StructureWithValueInCondition {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace StructureWithValueInCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithValueInConditionView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return StructureWithValueInCondition::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithValueInConditionView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return StructureWithValueInCondition::MaxSizeInBytes();
+}
+
+namespace StructureWithValueInCondition {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace StructureWithValueInCondition
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithValueInConditionView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return StructureWithValueInCondition::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithValueInConditionView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return StructureWithValueInCondition::MinSizeInBytes();
+}
+namespace StructureWithValuesInLocation {
+
+}  // namespace StructureWithValuesInLocation
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ GenericStructureWithValuesInLocationView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithValuesInLocationView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericStructureWithValuesInLocationView<Storage>::EmbossReservedVirtualTwoXView
+GenericStructureWithValuesInLocationView<Storage>::two_x() const {
+  return
+      typename GenericStructureWithValuesInLocationView<Storage>::EmbossReservedVirtualTwoXView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithValuesInLocationView<Storage>::has_two_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/2, 0>>, 32>>
+
+ GenericStructureWithValuesInLocationView<Storage>::offset_two_x()
+    const {
+
+  if ( has_offset_two_x().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = two_x();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int64_t>(static_cast</**/::std::int64_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int64_t>());
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = emboss_reserved_local_subexpr_2;
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/2, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<2,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/2, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithValuesInLocationView<Storage>::has_offset_two_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+ GenericStructureWithValuesInLocationView<Storage>::size_two_x()
+    const {
+
+  if ( has_size_two_x().ValueOr(false)) {
+    const auto emboss_reserved_local_subexpr_1 = two_x();
+    const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok()    ? ::emboss::support::Maybe</**/::std::int64_t>(static_cast</**/::std::int64_t>(emboss_reserved_local_subexpr_1.UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int64_t>());
+
+    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_2;
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   4>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithValuesInLocationView<Storage>::has_size_two_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericStructureWithValuesInLocationView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericStructureWithValuesInLocationView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericStructureWithValuesInLocationView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithValuesInLocationView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace StructureWithValuesInLocation {
+inline constexpr ::std::int64_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int64_t>(static_cast</**/::std::int64_t>(8589934594LL)).ValueOrDefault();
+}
+}  // namespace StructureWithValuesInLocation
+
+template <class Storage>
+inline constexpr ::std::int64_t
+GenericStructureWithValuesInLocationView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return StructureWithValuesInLocation::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int64_t
+GenericStructureWithValuesInLocationView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return StructureWithValuesInLocation::MaxSizeInBytes();
+}
+
+namespace StructureWithValuesInLocation {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace StructureWithValuesInLocation
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithValuesInLocationView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return StructureWithValuesInLocation::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithValuesInLocationView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return StructureWithValuesInLocation::MinSizeInBytes();
+}
+namespace StructureWithBoolValue {
+
+}  // namespace StructureWithBoolValue
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ GenericStructureWithBoolValueView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithBoolValueView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericStructureWithBoolValueView<Storage>::EmbossReservedVirtualXIsTenView
+GenericStructureWithBoolValueView<Storage>::x_is_ten() const {
+  return
+      typename GenericStructureWithBoolValueView<Storage>::EmbossReservedVirtualXIsTenView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithBoolValueView<Storage>::has_x_is_ten() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace StructureWithBoolValue {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace StructureWithBoolValue
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithBoolValueView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return StructureWithBoolValue::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithBoolValueView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return StructureWithBoolValue::IntrinsicSizeInBytes();
+}
+
+namespace StructureWithBoolValue {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace StructureWithBoolValue
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithBoolValueView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return StructureWithBoolValue::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithBoolValueView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return StructureWithBoolValue::MaxSizeInBytes();
+}
+
+namespace StructureWithBoolValue {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace StructureWithBoolValue
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithBoolValueView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return StructureWithBoolValue::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithBoolValueView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return StructureWithBoolValue::MinSizeInBytes();
+}
+namespace StructureWithEnumValue {
+
+}  // namespace StructureWithEnumValue
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ GenericStructureWithEnumValueView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithEnumValueView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericStructureWithEnumValueView<Storage>::EmbossReservedVirtualXSizeView
+GenericStructureWithEnumValueView<Storage>::x_size() const {
+  return
+      typename GenericStructureWithEnumValueView<Storage>::EmbossReservedVirtualXSizeView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithEnumValueView<Storage>::has_x_size() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace StructureWithEnumValue {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace StructureWithEnumValue
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithEnumValueView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return StructureWithEnumValue::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithEnumValueView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return StructureWithEnumValue::IntrinsicSizeInBytes();
+}
+
+namespace StructureWithEnumValue {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace StructureWithEnumValue
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithEnumValueView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return StructureWithEnumValue::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithEnumValueView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return StructureWithEnumValue::MaxSizeInBytes();
+}
+
+namespace StructureWithEnumValue {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace StructureWithEnumValue
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithEnumValueView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return StructureWithEnumValue::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithEnumValueView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return StructureWithEnumValue::MinSizeInBytes();
+}
+namespace StructureWithBitsWithValue {
+
+}  // namespace StructureWithBitsWithValue
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericBitsWithValueView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ GenericStructureWithBitsWithValueView<Storage>::b()
+    const {
+
+  if ( has_b().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericBitsWithValueView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericBitsWithValueView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithBitsWithValueView<Storage>::has_b() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericStructureWithBitsWithValueView<Storage>::EmbossReservedVirtualAliasOfBSumView
+GenericStructureWithBitsWithValueView<Storage>::alias_of_b_sum() const {
+  return
+      typename GenericStructureWithBitsWithValueView<Storage>::EmbossReservedVirtualAliasOfBSumView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithBitsWithValueView<Storage>::has_alias_of_b_sum() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureWithBitsWithValueView<Storage>::has_alias_of_b_a() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace StructureWithBitsWithValue {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace StructureWithBitsWithValue
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithBitsWithValueView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return StructureWithBitsWithValue::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithBitsWithValueView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return StructureWithBitsWithValue::IntrinsicSizeInBytes();
+}
+
+namespace StructureWithBitsWithValue {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace StructureWithBitsWithValue
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithBitsWithValueView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return StructureWithBitsWithValue::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithBitsWithValueView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return StructureWithBitsWithValue::MaxSizeInBytes();
+}
+
+namespace StructureWithBitsWithValue {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace StructureWithBitsWithValue
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithBitsWithValueView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return StructureWithBitsWithValue::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureWithBitsWithValueView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return StructureWithBitsWithValue::MinSizeInBytes();
+}
+namespace BitsWithValue {
+
+}  // namespace BitsWithValue
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericBitsWithValueView<Storage>::a()
+    const {
+
+  if ( has_a().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(16LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBitsWithValueView<Storage>::has_a() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 16>>
+
+ GenericBitsWithValueView<Storage>::b()
+    const {
+
+  if ( has_b().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(16LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(16LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 16>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   16>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 16>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBitsWithValueView<Storage>::has_b() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericBitsWithValueView<Storage>::EmbossReservedVirtualSumView
+GenericBitsWithValueView<Storage>::sum() const {
+  return
+      typename GenericBitsWithValueView<Storage>::EmbossReservedVirtualSumView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericBitsWithValueView<Storage>::has_sum() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace BitsWithValue {
+inline constexpr ::std::int32_t IntrinsicSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(32LL)).ValueOrDefault();
+}
+}  // namespace BitsWithValue
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBitsWithValueView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
+  return BitsWithValue::IntrinsicSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBitsWithValueView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
+  return BitsWithValue::IntrinsicSizeInBits();
+}
+
+namespace BitsWithValue {
+inline constexpr ::std::int32_t MaxSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(32LL)).ValueOrDefault();
+}
+}  // namespace BitsWithValue
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBitsWithValueView<Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
+  return BitsWithValue::MaxSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBitsWithValueView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
+  return BitsWithValue::MaxSizeInBits();
+}
+
+namespace BitsWithValue {
+inline constexpr ::std::int32_t MinSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(32LL)).ValueOrDefault();
+}
+}  // namespace BitsWithValue
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBitsWithValueView<Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
+  return BitsWithValue::MinSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericBitsWithValueView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
+  return BitsWithValue::MinSizeInBits();
+}
+namespace StructureUsingForeignConstants {
+
+}  // namespace StructureUsingForeignConstants
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 32>>
+
+ GenericStructureUsingForeignConstantsView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   10>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<32, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 10>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericStructureUsingForeignConstantsView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace StructureUsingForeignConstants {
+inline constexpr ::std::int32_t one_hundred() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(100LL)).ValueOrDefault();
+}
+}  // namespace StructureUsingForeignConstants
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureUsingForeignConstantsView<Storage>::EmbossReservedVirtualOneHundredView::Read() {
+  return StructureUsingForeignConstants::one_hundred();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureUsingForeignConstantsView<
+    Storage>::EmbossReservedVirtualOneHundredView::UncheckedRead() {
+  return StructureUsingForeignConstants::one_hundred();
+}
+
+namespace StructureUsingForeignConstants {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(14LL)).ValueOrDefault();
+}
+}  // namespace StructureUsingForeignConstants
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureUsingForeignConstantsView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return StructureUsingForeignConstants::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureUsingForeignConstantsView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return StructureUsingForeignConstants::IntrinsicSizeInBytes();
+}
+
+namespace StructureUsingForeignConstants {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(14LL)).ValueOrDefault();
+}
+}  // namespace StructureUsingForeignConstants
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureUsingForeignConstantsView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return StructureUsingForeignConstants::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureUsingForeignConstantsView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return StructureUsingForeignConstants::MaxSizeInBytes();
+}
+
+namespace StructureUsingForeignConstants {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(14LL)).ValueOrDefault();
+}
+}  // namespace StructureUsingForeignConstants
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureUsingForeignConstantsView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return StructureUsingForeignConstants::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericStructureUsingForeignConstantsView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return StructureUsingForeignConstants::MinSizeInBytes();
+}
+namespace SubfieldOfAlias {
+namespace Header {
+
+}  // namespace Header
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 16>>
+
+ GenericHeaderView<Storage>::size()
+    const {
+
+  if ( has_size().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 16>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 16>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericHeaderView<Storage>::has_size() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 16>>
+
+ GenericHeaderView<Storage>::message_id()
+    const {
+
+  if ( has_message_id().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 16>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   2>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<16, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 2>>, 16>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericHeaderView<Storage>::has_message_id() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace Header {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace Header
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericHeaderView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return Header::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericHeaderView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return Header::IntrinsicSizeInBytes();
+}
+
+namespace Header {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace Header
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericHeaderView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return Header::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericHeaderView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return Header::MaxSizeInBytes();
+}
+
+namespace Header {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace Header
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericHeaderView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return Header::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericHeaderView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return Header::MinSizeInBytes();
+}
+
+}  // namespace SubfieldOfAlias
+
+
+template <class Storage>
+inline typename ::emboss::test::SubfieldOfAlias::GenericHeaderView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericSubfieldOfAliasView<Storage>::header()
+    const {
+
+  if ( has_header().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::SubfieldOfAlias::GenericHeaderView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::SubfieldOfAlias::GenericHeaderView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSubfieldOfAliasView<Storage>::has_header() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSubfieldOfAliasView<Storage>::has_h() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericSubfieldOfAliasView<Storage>::has_size() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace SubfieldOfAlias {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace SubfieldOfAlias
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSubfieldOfAliasView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return SubfieldOfAlias::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSubfieldOfAliasView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return SubfieldOfAlias::IntrinsicSizeInBytes();
+}
+
+namespace SubfieldOfAlias {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace SubfieldOfAlias
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSubfieldOfAliasView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return SubfieldOfAlias::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSubfieldOfAliasView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return SubfieldOfAlias::MaxSizeInBytes();
+}
+
+namespace SubfieldOfAlias {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL)).ValueOrDefault();
+}
+}  // namespace SubfieldOfAlias
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSubfieldOfAliasView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return SubfieldOfAlias::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericSubfieldOfAliasView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return SubfieldOfAlias::MinSizeInBytes();
+}
+namespace RestrictedAlias {
+
+}  // namespace RestrictedAlias
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericBitsWithValueView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+ GenericRestrictedAliasView<Storage>::a_b()
+    const {
+
+  if ( has_a_b().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericBitsWithValueView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericBitsWithValueView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 32>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRestrictedAliasView<Storage>::has_a_b() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 8>>
+
+ GenericRestrictedAliasView<Storage>::alias_switch()
+    const {
+
+  if ( has_alias_switch().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   4>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 4>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRestrictedAliasView<Storage>::has_alias_switch() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRestrictedAliasView<Storage>::has_a_b_alias() const {
+  return ::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((alias_switch().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(alias_switch().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)));
+}
+
+
+namespace RestrictedAlias {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)).ValueOrDefault();
+}
+}  // namespace RestrictedAlias
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRestrictedAliasView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return RestrictedAlias::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRestrictedAliasView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return RestrictedAlias::IntrinsicSizeInBytes();
+}
+
+namespace RestrictedAlias {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)).ValueOrDefault();
+}
+}  // namespace RestrictedAlias
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRestrictedAliasView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return RestrictedAlias::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRestrictedAliasView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return RestrictedAlias::MaxSizeInBytes();
+}
+
+namespace RestrictedAlias {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(5LL)).ValueOrDefault();
+}
+}  // namespace RestrictedAlias
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRestrictedAliasView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return RestrictedAlias::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRestrictedAliasView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return RestrictedAlias::MinSizeInBytes();
+}
+namespace HasField {
+namespace X {
+
+}  // namespace X
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericXView<Storage>::v()
+    const {
+
+  if ( has_v().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericXView<Storage>::has_v() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericXView<Storage>::y()
+    const {
+
+  if ( has_y().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericXView<Storage>::has_y() const {
+  return ::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((v().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(v().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)));
+}
+
+
+template <class Storage>
+inline typename GenericXView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericXView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericXView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericXView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace X {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace X
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericXView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return X::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericXView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return X::MaxSizeInBytes();
+}
+
+namespace X {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace X
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericXView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return X::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericXView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return X::MinSizeInBytes();
+}
+
+}  // namespace HasField
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericHasFieldView<Storage>::z()
+    const {
+
+  if ( has_z().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericHasFieldView<Storage>::has_z() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::HasField::GenericXView<typename Storage::template OffsetStorageType</**/0, 1>>
+
+ GenericHasFieldView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::HasField::GenericXView<typename Storage::template OffsetStorageType</**/0, 1>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::HasField::GenericXView<typename Storage::template OffsetStorageType</**/0, 1>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericHasFieldView<Storage>::has_x() const {
+  return ::emboss::support::GreaterThan</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((z().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(z().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(10LL)));
+}
+
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericHasFieldView<Storage>::has_y() const {
+  return x().has_y();
+}
+
+
+template <class Storage>
+inline typename GenericHasFieldView<Storage>::EmbossReservedVirtualXHasYView
+GenericHasFieldView<Storage>::x_has_y() const {
+  return
+      typename GenericHasFieldView<Storage>::EmbossReservedVirtualXHasYView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericHasFieldView<Storage>::has_x_has_y() const {
+  return has_x();
+}
+
+
+template <class Storage>
+inline typename GenericHasFieldView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericHasFieldView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericHasFieldView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericHasFieldView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace HasField {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(3LL)).ValueOrDefault();
+}
+}  // namespace HasField
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericHasFieldView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return HasField::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericHasFieldView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return HasField::MaxSizeInBytes();
+}
+
+namespace HasField {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace HasField
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericHasFieldView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return HasField::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericHasFieldView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return HasField::MinSizeInBytes();
+}
+namespace VirtualUnconditionallyUsesConditional {
+
+}  // namespace VirtualUnconditionallyUsesConditional
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericVirtualUnconditionallyUsesConditionalView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericVirtualUnconditionallyUsesConditionalView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+ GenericVirtualUnconditionallyUsesConditionalView<Storage>::xc()
+    const {
+
+  if ( has_xc().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   1>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 1>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericVirtualUnconditionallyUsesConditionalView<Storage>::has_xc() const {
+  return ::emboss::support::Equal</**/::std::int32_t, bool, ::std::int32_t, ::std::int32_t>((x().Ok()    ? ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(x().UncheckedRead()))    : ::emboss::support::Maybe</**/::std::int32_t>()), ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL)));
+}
+
+
+template <class Storage>
+inline typename GenericVirtualUnconditionallyUsesConditionalView<Storage>::EmbossReservedVirtualXNorXcView
+GenericVirtualUnconditionallyUsesConditionalView<Storage>::x_nor_xc() const {
+  return
+      typename GenericVirtualUnconditionallyUsesConditionalView<Storage>::EmbossReservedVirtualXNorXcView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericVirtualUnconditionallyUsesConditionalView<Storage>::has_x_nor_xc() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericVirtualUnconditionallyUsesConditionalView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
+GenericVirtualUnconditionallyUsesConditionalView<Storage>::IntrinsicSizeInBytes() const {
+  return
+      typename GenericVirtualUnconditionallyUsesConditionalView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericVirtualUnconditionallyUsesConditionalView<Storage>::has_IntrinsicSizeInBytes() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace VirtualUnconditionallyUsesConditional {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(2LL)).ValueOrDefault();
+}
+}  // namespace VirtualUnconditionallyUsesConditional
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericVirtualUnconditionallyUsesConditionalView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return VirtualUnconditionallyUsesConditional::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericVirtualUnconditionallyUsesConditionalView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return VirtualUnconditionallyUsesConditional::MaxSizeInBytes();
+}
+
+namespace VirtualUnconditionallyUsesConditional {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace VirtualUnconditionallyUsesConditional
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericVirtualUnconditionallyUsesConditionalView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return VirtualUnconditionallyUsesConditional::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericVirtualUnconditionallyUsesConditionalView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return VirtualUnconditionallyUsesConditional::MinSizeInBytes();
+}
+namespace UsesSize {
+namespace R {
+
+}  // namespace R
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericRView<Storage>::q()
+    const {
+
+  if ( has_q().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRView<Storage>::has_q() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace R {
+inline constexpr ::std::int32_t IntrinsicSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace R
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
+  return R::IntrinsicSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
+  return R::IntrinsicSizeInBits();
+}
+
+template <class Storage>
+inline typename GenericRView<Storage>::EmbossReservedVirtualQPlusBitSizeView
+GenericRView<Storage>::q_plus_bit_size() const {
+  return
+      typename GenericRView<Storage>::EmbossReservedVirtualQPlusBitSizeView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericRView<Storage>::has_q_plus_bit_size() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace R {
+inline constexpr ::std::int32_t MaxSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace R
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRView<Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
+  return R::MaxSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
+  return R::MaxSizeInBits();
+}
+
+namespace R {
+inline constexpr ::std::int32_t MinSizeInBits() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace R
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRView<Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
+  return R::MinSizeInBits();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericRView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
+  return R::MinSizeInBits();
+}
+
+}  // namespace UsesSize
+
+
+template <class Storage>
+inline typename ::emboss::test::UsesSize::GenericRView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericUsesSizeView<Storage>::r()
+    const {
+
+  if ( has_r().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::UsesSize::GenericRView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::UsesSize::GenericRView<typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericUsesSizeView<Storage>::has_r() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace UsesSize {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace UsesSize
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericUsesSizeView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return UsesSize::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericUsesSizeView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return UsesSize::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline typename GenericUsesSizeView<Storage>::EmbossReservedVirtualRQPlusByteSizeView
+GenericUsesSizeView<Storage>::r_q_plus_byte_size() const {
+  return
+      typename GenericUsesSizeView<Storage>::EmbossReservedVirtualRQPlusByteSizeView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericUsesSizeView<Storage>::has_r_q_plus_byte_size() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace UsesSize {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace UsesSize
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericUsesSizeView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return UsesSize::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericUsesSizeView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return UsesSize::MaxSizeInBytes();
+}
+
+namespace UsesSize {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace UsesSize
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericUsesSizeView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return UsesSize::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericUsesSizeView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return UsesSize::MinSizeInBytes();
+}
+namespace UsesExternalSize {
+
+}  // namespace UsesExternalSize
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericStructureWithConstantsView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+ GenericUsesExternalSizeView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericStructureWithConstantsView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericStructureWithConstantsView<typename Storage::template OffsetStorageType</**/0, 0>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericUsesExternalSizeView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename ::emboss::test::GenericStructureWithConstantsView<typename Storage::template OffsetStorageType</**/0, 4>>
+
+ GenericUsesExternalSizeView<Storage>::y()
+    const {
+
+  if ( has_y().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(4LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::test::GenericStructureWithConstantsView<typename Storage::template OffsetStorageType</**/0, 4>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   4>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::test::GenericStructureWithConstantsView<typename Storage::template OffsetStorageType</**/0, 4>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericUsesExternalSizeView<Storage>::has_y() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace UsesExternalSize {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace UsesExternalSize
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericUsesExternalSizeView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return UsesExternalSize::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericUsesExternalSizeView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return UsesExternalSize::IntrinsicSizeInBytes();
+}
+
+namespace UsesExternalSize {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace UsesExternalSize
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericUsesExternalSizeView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return UsesExternalSize::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericUsesExternalSizeView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return UsesExternalSize::MaxSizeInBytes();
+}
+
+namespace UsesExternalSize {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(8LL)).ValueOrDefault();
+}
+}  // namespace UsesExternalSize
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericUsesExternalSizeView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return UsesExternalSize::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericUsesExternalSizeView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return UsesExternalSize::MinSizeInBytes();
+}
+namespace ImplicitWriteBack {
+
+}  // namespace ImplicitWriteBack
+
+
+template <class Storage>
+inline typename ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+ GenericImplicitWriteBackView<Storage>::x()
+    const {
+
+  if ( has_x().ValueOr(false)) {
+
+    auto emboss_reserved_local_size = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL));
+    auto emboss_reserved_local_offset = ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(0LL));
+    if (emboss_reserved_local_size.Known() &&
+        emboss_reserved_local_size.ValueOr(0) >= 0 &&
+        emboss_reserved_local_offset.Known() &&
+        emboss_reserved_local_offset.ValueOr(0) >= 0) {
+        return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+(
+                 backing_
+                        .template GetOffsetStorage<0,
+                                                   0>(
+                                emboss_reserved_local_offset.ValueOrDefault(),
+                                emboss_reserved_local_size.ValueOrDefault()));
+    }
+  }
+  return ::emboss::prelude::UIntView<
+    /**/ ::emboss::support::FixedSizeViewParameters<8, ::emboss::support::AllValuesAreOk>,
+    typename ::emboss::support::BitBlock</**/::emboss::support::LittleEndianByteOrderer<typename Storage::template OffsetStorageType</**/0, 0>>, 8>>
+
+();
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericImplicitWriteBackView<Storage>::has_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericImplicitWriteBackView<Storage>::EmbossReservedVirtualXPlusTenView
+GenericImplicitWriteBackView<Storage>::x_plus_ten() const {
+  return
+      typename GenericImplicitWriteBackView<Storage>::EmbossReservedVirtualXPlusTenView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericImplicitWriteBackView<Storage>::has_x_plus_ten() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericImplicitWriteBackView<Storage>::EmbossReservedVirtualTenPlusXView
+GenericImplicitWriteBackView<Storage>::ten_plus_x() const {
+  return
+      typename GenericImplicitWriteBackView<Storage>::EmbossReservedVirtualTenPlusXView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericImplicitWriteBackView<Storage>::has_ten_plus_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericImplicitWriteBackView<Storage>::EmbossReservedVirtualXMinusTenView
+GenericImplicitWriteBackView<Storage>::x_minus_ten() const {
+  return
+      typename GenericImplicitWriteBackView<Storage>::EmbossReservedVirtualXMinusTenView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericImplicitWriteBackView<Storage>::has_x_minus_ten() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericImplicitWriteBackView<Storage>::EmbossReservedVirtualTenMinusXView
+GenericImplicitWriteBackView<Storage>::ten_minus_x() const {
+  return
+      typename GenericImplicitWriteBackView<Storage>::EmbossReservedVirtualTenMinusXView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericImplicitWriteBackView<Storage>::has_ten_minus_x() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+template <class Storage>
+inline typename GenericImplicitWriteBackView<Storage>::EmbossReservedVirtualTenMinusXPlusTenView
+GenericImplicitWriteBackView<Storage>::ten_minus_x_plus_ten() const {
+  return
+      typename GenericImplicitWriteBackView<Storage>::EmbossReservedVirtualTenMinusXPlusTenView(
+          *this);
+}
+
+template <class Storage>
+inline ::emboss::support::Maybe<bool>
+GenericImplicitWriteBackView<Storage>::has_ten_minus_x_plus_ten() const {
+  return ::emboss::support::Maybe</**/bool>(true);
+}
+
+
+namespace ImplicitWriteBack {
+inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace ImplicitWriteBack
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericImplicitWriteBackView<Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
+  return ImplicitWriteBack::IntrinsicSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericImplicitWriteBackView<
+    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
+  return ImplicitWriteBack::IntrinsicSizeInBytes();
+}
+
+namespace ImplicitWriteBack {
+inline constexpr ::std::int32_t MaxSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace ImplicitWriteBack
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericImplicitWriteBackView<Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
+  return ImplicitWriteBack::MaxSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericImplicitWriteBackView<
+    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
+  return ImplicitWriteBack::MaxSizeInBytes();
+}
+
+namespace ImplicitWriteBack {
+inline constexpr ::std::int32_t MinSizeInBytes() {
+  return ::emboss::support::Maybe</**/::std::int32_t>(static_cast</**/::std::int32_t>(1LL)).ValueOrDefault();
+}
+}  // namespace ImplicitWriteBack
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericImplicitWriteBackView<Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
+  return ImplicitWriteBack::MinSizeInBytes();
+}
+
+template <class Storage>
+inline constexpr ::std::int32_t
+GenericImplicitWriteBackView<
+    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
+  return ImplicitWriteBack::MinSizeInBytes();
+}
+
+
+
+}  // namespace test
+
+
+
+}  // namespace emboss
+
+
+
+/* NOLINTEND */
+
+#endif  // TESTDATA_VIRTUAL_FIELD_EMB_H_
+
