[fidl][docs] Fill out bindings spec and publish FTP-057

This also moves it under the FIDL language reference instead of
the FIDL bindings reference, as the latter is geared towards app
developers not bindings authors.

Change-Id: I8de08bd2a8b4b8e32d6acf5b5bb19f3bb61be1f0
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/391556
Commit-Queue: Felix Zhu <fcz@google.com>
Reviewed-by: Pascal Perez <pascallouis@google.com>
diff --git a/docs/contribute/governance/fidl/README.md b/docs/contribute/governance/fidl/README.md
index cb8da6f..da89bdc 100644
--- a/docs/contribute/governance/fidl/README.md
+++ b/docs/contribute/governance/fidl/README.md
@@ -35,6 +35,7 @@
 [FTP-028](ftp/ftp-028.md) | 2019-04-01 | 2019-12-12 | Handle Rights – The Right Stuff
 [FTP-054](ftp/ftp-054.md) | 2019-11-21 | 2019-12-12 | Parameter Attributes &mdash; A Chance to Write Self Documenting APIs
 [FTP-049](ftp/ftp-049.md) | 2019-11-20 | 2019-12-19 | FIDL Tuning Process Evolution
+[FTP-057](ftp/ftp-057.md) | 2020-01-16 | 2020-01-23 | Default No Handles
 [FTP-059](ftp/ftp-059.md) | 2020-03-16 | 2020-03-19 | Reserved Bits in Vector/String/Array Count Fields
 [FTP-040](ftp/ftp-040.md) | 2019-04-07 | 2020-05-14 | Identifier Uniqueness &mdash; SnowFlake vs SNOW_FLAKE
 
diff --git a/docs/contribute/governance/fidl/ftp/_toc.yaml b/docs/contribute/governance/fidl/ftp/_toc.yaml
index 6f8a323..a84bb72 100644
--- a/docs/contribute/governance/fidl/ftp/_toc.yaml
+++ b/docs/contribute/governance/fidl/ftp/_toc.yaml
@@ -82,5 +82,7 @@
   path: /docs/contribute/governance/fidl/ftp/ftp-049.md
 - title: "FTP-054: Parameter Attributes"
   path: /docs/contribute/governance/fidl/ftp/ftp-054.md
+- title: "FTP-057: Default No Handles"
+  path: /docs/contribute/governance/fidl/ftp/ftp-057.md
 - title: "FTP-059: Reserved Bits in Vector/String/Array Count Fields"
   path: /docs/contribute/governance/fidl/ftp/ftp-059.md
diff --git a/docs/contribute/governance/fidl/ftp/ftp-057.md b/docs/contribute/governance/fidl/ftp/ftp-057.md
new file mode 100644
index 0000000..32f80241
--- /dev/null
+++ b/docs/contribute/governance/fidl/ftp/ftp-057.md
@@ -0,0 +1,342 @@
+# [FTP](../README.md)-057: Default No Handles
+
+_*"Look Ma, no hand(le)s!"*_
+
+Field     | Value
+----------|--------------------------
+Status    | Accepted
+Authors   | mkember@google.com
+Submitted | 2020-01-16
+Reviewed  | 2020-01-23
+
+## Summary
+
+We propose to disallow handles in FIDL type declarations by default, and add a
+new keyword `resource` [[1]](#Footnote1) to mark types that are allowed to
+contain handles or other resource types. Adding or removing a `resource`
+modifier MAY be a source-breaking change.
+
+## Motivation {#motivation}
+
+A distinctive feature of FIDL is its support for [Zircon
+handles](/docs/concepts/kernel/handles.md). Handles are 32-bit integers in
+memory, but they are treated specially: they must be moved rather than copied,
+and they must be closed to avoid leaking resources. This special treatment leads
+to problems when considering features that only make sense for plain data
+without handles. Although FIDL bindings _can_ conditionally enable code based on
+the presence of handles, doing so is undesirable because it breaks evolvability
+guarantees. For example, adding a field to a table is normally safe, but adding
+a handle field would become source-breaking—not only for that table, but for all
+types transitively containing it. This pushes bindings to be conservative,
+always assuming that types might contain handles even if the library author
+never intends to add them.
+
+The need to accommodate handles has led to compromise:
+
+* In Dart, an effort to implement FIDL to JSON encoding received pushback
+  because it would only work on types without handles, harming evolvability. It
+  was ultimately built using the `MaxHandles` attribute, but this was a
+  temporary solution because the attribute only applies to the outermost type,
+  not to all types transitively reachable from it.
+* In Rust, adding a handle to a type for the first time is source-breaking
+  because the type will no longer derive the `Clone` trait. (Properly cloning a
+  handle requires invoking the
+  [zx_handle_duplicate](/docs/reference/syscalls/handle_duplicate.md) syscall,
+  which can fail.)
+* The Rust bindings for protocols take FIDL objects by mutable reference and
+  zero out handles, rather than explicitly taking ownership, so that objects
+  without handles can be reused afterwards.
+
+All these cases can be handled in a safer, more ergonomic way if we require
+library authors to indicate whether a type may contain handles, and if changing
+the indication is expected to be source-breaking.
+
+## Design
+
+### Terminology
+
+A FIDL type is either a **value** type or a **resource** type. Resource types
+include:
+
+*   `handle` and <code>handle<<em>H</em>></code> where <code><em>H</em></code>
+    is a handle subtype
+*   <code><em>P</em></code> and <code>request<<em>P</em>></code> where
+    <code><em>P</em></code> is the name of a protocol
+*   a struct, table, or union declared with the <code>resource</code> modifier
+*   a type alias that refers to a resource type
+*   a newtype [FTP-052][ftp-052] that wraps a resource type
+*   <code><em>T</em>?</code> where <code><em>T</em></code> is a non-nullable
+    resource type
+*   <code>array<<em>T</em>></code> and <code>vector<<em>T</em>></code> where
+    <code><em>T</em></code> is a resource type
+
+All other types are value types.
+
+When the `resource` modifier is used correctly, value types never contain
+handles, whereas resource types may (now, or in the future) contain handles.
+
+### Language
+
+A new modifier `resource` can be applied to struct, table, and union
+declarations.
+
+Without `resource`, the declaration is not allowed to contain resource types.
+The FIDL compiler must verify this. It only needs to check direct fields: if _A_
+contains _B_, neither are marked as resources, and _B_ contains a handle, then
+compilation will fail due to _B_ and there is no need for a separate error
+message about _A_ transitively containing a handle.
+
+With `resource`, the declaration is allowed to contain resource types. The new
+type it declares is also considered a resource type, even if it does not contain
+resources.
+
+In principle the language could allow `resource` on newtype declarations
+[FTP-052][ftp-052]. However, there is no practical use for a resource newtype
+wrapping a value type, so instead newtypes implicitly inherit value/resource
+status from the type they wrap.
+
+### Grammar
+
+This proposal modifies one rule in the [FIDL grammar](/docs/reference/fidl/language/grammar.md):
+
+```
+declaration-modifiers = "strict" | "resource" ;
+```
+
+### JSON IR
+
+This proposal adds a key `"resource"` with a boolean value to all objects in the
+`"struct_declarations"`, `"table_declarations"`, and `"union_declarations"`
+arrays.
+
+Note that this key is not redundant with `"max_handles"`. Value types must have
+`max_handles` set to zero, but resource types can have any number of
+`max_handles`, as it reflects the actual contents of the declaration (as opposed
+to the library author’s intent to allow handles).
+
+### Bindings {#bindings}
+
+This proposal does not include specific changes to the bindings. However, it
+enables FIDL bindings authors (including the FIDL team) to address the issues
+discussed in  [Motivation](#motivation). Here are some examples made possible by
+this FTP, but not required in accepting it:
+
+*   Implement JSON serialization and serialization on value types (or more
+    likely the FIDL Text format rather than JSON, as proposed in
+    [FTP-058][ftp-058].
+*   Use different type signatures for the C++ `Clone()` method on value/resource
+    types, to emphasize that only resource cloning can fail.
+*   Make Rust protocols take value-type arguments as `&T` and resource-type
+    arguments as `T`, instead of using `&mut T` for both and only mutating the
+    resource types.
+
+### API Rubric
+
+The API rubric should provide guidance on when to use `resource`. Some simple
+cases:
+
+*   A struct with no resource types SHOULD NOT be marked `resource`, since
+    structs are not designed to be extended (adding a handle later would in most
+    cases break ABI).
+*   A strict table or union with no resource types SHOULD NOT be marked
+    `resource`, since the strictness already signals that modifying its fields
+    is a source-breaking change.
+
+It should also address the case of flexible tables and unions that do not
+initially have handles. For instance, we might want to recommend erring on one
+side or the other depending on the purpose of the library, how widely it will be
+used, the anticipated cost of source-breaking changes in the languages being
+used, and other factors.
+
+## Implementation Strategy
+
+The high-level implementation steps include:
+
+*   Parse the `resource` keyword in fidlc.
+*   Migrate existing FIDL libraries to use `resource` (more on this in
+    [Unknowns](#unknowns).
+*   Verify value/resource type rules in fidlc, with tests.
+*   Store the `resource` flag in the JSON IR and expose it in fidlgen.
+
+## Ergonomics {#ergonomics}
+
+This proposal makes FIDL more complex since it introduces a new concept. Unlike
+other FIDL constructs such as “struct” and “protocol,” new users are unlikely to
+guess what “resource” means, so they will need to learn from documentation.
+
+It is arguable whether this proposal makes the FIDL language more or less
+ergonomic. It helps by drawing attention to declarations that contain handles,
+especially if the actual handle values are hidden in nested structures. Anyone
+skimming a library will immediately see that a structure carries handles, not
+just data. On the other hand, it might feel less ergonomic to worry about
+whether to use `resource` and to type the keyword. Changing one declaration from
+value to resource could have a painful cascading effect where many types must
+become resources (though this can be seen as a good thing, since otherwise it
+would show up as source breakage).
+
+The increased complexity is justified by improvements in FIDL bindings. With the
+freedom to offer different APIs for value types and resource types, the bindings
+can be made safer and more ergonomic. For examples of these improvements, see
+[Bindings](#bindings).
+
+## Documentation and Examples
+
+The following tasks need to be done:
+
+*   Update all documentation involving handles to use `resource` as appropriate.
+*   Update the FIDL Language Specification to explain the `resource` modifier.
+*   Mention `resource` in the FIDL Tutorial. There should be a short note
+    explaining all the modifiers (so, `strict` and `resource`).
+*   Provide guidance on whether a new type without handles should be a resource.
+*   Once bindings take advantage of the value/resource distinction, update their
+    documentation to note the differences between APIs offered by value types
+    and resource types, and provide instructions for transitioning between them
+    (if possible).
+
+## Backwards Compatibility
+
+This proposal has no impact on ABI compatibility.
+
+Adding or removing a `resource` modifier is **neither source-compatible nor
+transitionable**,[[2]](#Footnote2) in the sense of
+[FTP-024](/docs/contribute/governance/fidl/ftp/ftp-024.md). The bindings are
+explicitly allowed to generate incompatible APIs for two types that differ only
+in the presence of the modifier, and it may in fact be impossible to write code
+that compiles before and after adding/removing the modifier. Library authors
+wishing to transition to/from `resource` in a source-compatible manner must
+create new types and methods instead of changing existing ones.
+
+Once bindings authors start taking advantage of the value/resource distinction,
+we will revisit this decision. It might be worthwhile to require a
+transitionable path (perhaps using an intermediate stage with the
+`[Transitional]` attribute). At the outset, this is unclear: it might be too
+restrictive, undermining potential API improvements this proposal is meant to
+enable.
+
+## Performance
+
+This proposal has negligible impact on build performance: the FIDL compiler will
+do slightly more work to parse the new keyword and validate its use. It has no
+direct impact on IPC performance. It might enable a small improvement in some
+languages if bindings use the value/resource distinction to create APIs that
+discourage unnecessary copies. For example, there should be no need to clone a
+value-type object in order to send it multiple times.
+
+## Security
+
+This proposal does not directly affect security, but it enables bindings to
+provide safer APIs. For example, C++ could force error handling on `Clone()` for
+resource types with `[[nodiscard]]`, or Rust could take resource-type method
+arguments by move to prevent accidental use of the mutated object afterwards.
+These kinds of changes could prevent bugs, including security bugs.
+
+## Testing
+
+ This feature will be tested in the following ways:
+*   Add tests in fidlc for the parsing and validation code paths. These tests
+    should exercise a variety of cases where a declaration marked `resource` (or
+    not) fails to conform to the definition of a resource type (or value type).
+*   Add some resource type declarations to the goldens, in addition to fixing
+    existing declarations that need `resource`.
+*   Update the [fidl-changes test suite](/garnet/tests/fidl-changes/) to
+    demonstrate the steps for a transition from value type to resource type and
+    vice versa.
+
+
+## Drawbacks, Alternatives, and Unknowns {#unknowns}
+
+This proposal introduces a new keyword, which makes the language more complex.
+Having too many keywords could be a problem; “strict resource union” is a bit of
+a mouthful.
+
+This proposal weakens FIDL evolvability guarantees in two ways:
+
+*   Before, adding a handle to a type was not expected to be a source-breaking
+    change. Now, this is explicitly allowed and expected (unless the type was
+    marked `resource` in anticipation of needing to add a handle).
+*   Before, a type could be declared with the future expectation of (1) adding
+    handles to it, and (2) being able to include it as a field in any other
+    type. Now, library authors must choose between (1) and (2) at the outset.
+
+There are two main alternatives to this proposal:
+
+*   **Do nothing**. Allow handles to be used anywhere, and live with the fact
+    that bindings must preserve source compatibility when adding or removing
+    handles.
+*   **Default allow handles**. Like this proposal, but assume declarations are
+    resource types by default, and require a `value` keyword to disallow
+    resource types in a declaration.
+
+The [Motivation](#motivation) and [Ergonomics](#ergonomics) sections argue
+against doing nothing. For the other alternative, experience has shown that most
+messages do not contain handles, and that passing handles in protocols requires
+care and upfront planning. In other words, value types are the common case, and
+the ability to add handles as an afterthought might not be as useful as it
+seems. This suggests that not allowing handles is the better default.
+
+This proposal mainly benefits end-developers using FIDL bindings, whereas its
+drawbacks apply to library authors who design the APIs. This tradeoff is in
+keeping with the [Fuchsia API Council
+Charter]/docs/concepts/api/council.md#values), which prioritizes end-developers
+over API designers and implementers.
+
+One more alternative has been suggested: **handles as references**. Instead of
+banning handles from value types, it would resolve the value/resource issues by
+representing handles as references. Cloning a structure containing a handle
+would just make another reference to the same handle. This could be accomplished
+using `shared_ptr` in C++, and it could greatly simplify things without needing
+to add the `resource` keyword. However, it has its challenges:
+
+*   All bindings would need a bookkeeping mechanism to ensure that a handle is
+    only closed once its last reference is gone. This could be difficult in some
+    languages.
+*   After sending a handle to another process, all other references to it would
+    become invalid, like dangling pointers. The convenience of treating handles
+    more like ordinary values means we have less compile-time safety in these
+    situations.
+*   As this involves changing types for all handles, it would likely be a
+    breaking change in all languages. A smooth transition would require a lot of
+    work.
+
+Several open questions remain for this proposal:
+
+*   How should we migrate existing FIDL libraries? Marking _all_ existing
+    declarations with `resource` would be safe, but not reflect library authors’
+    intentions. Marking only the bare minimum (i.e., types that contain handles)
+    would work, but might be too aggressive in assuming that anything without
+    handles was intended to never contain any.
+*   How will this feature interact with generic data types, if they are adopted?
+    For example, if we define a `Pair<A, B>` type, it should logically be a
+    resource type if `A` or `B` is a resource type, rather than having to
+    annotate `Pair` itself. Are there other cases where it is preferable to
+    derive whether a type is a resource?
+
+## Prior Art and References
+
+The goal of this proposal is to allow source-breaking changes to occur when
+changing a type’s value/resource status.
+[FTP-024](/docs/contribute/governance/fidl/ftp/ftp-024.md) is relevant to this
+goal, since it established the source-compatibility standard for FIDL. It also
+touched on the issue of handles making it difficult to use the `Clone` trait in
+Rust, which this proposal solves.
+
+We are not aware of other IPC systems addressing this exact issue
+(distinguishing types that may contain handles, or system resources). However,
+the concept of annotating types in a way that “infects” all use-sites is common
+in programming languages. For example, async functions in JavaScript, Python,
+and Rust have this behaviour, as well as the IO monad in Haskell.
+
+--------------------------------------------------------------------------------------------
+
+##### Footnote1
+
+An earlier version of this proposal instead called the keyword `entity`.
+
+##### Footnote2
+
+An earlier version of this proposal required the change to be transitionable.
+
+<!-- xrefs -->
+<!-- TODO: add links when these are published -->
+[ftp-052]: /docs/contribute/governance/fidl
+[ftp-058]: /docs/contribute/governance/fidl
diff --git a/docs/reference/fidl/bindings/_toc.yaml b/docs/reference/fidl/bindings/_toc.yaml
index bb1c206..911ce6d 100644
--- a/docs/reference/fidl/bindings/_toc.yaml
+++ b/docs/reference/fidl/bindings/_toc.yaml
@@ -14,5 +14,3 @@
   path: /docs/reference/fidl/bindings/rust-bindings.md
 - title: "Go bindings"
   path: /docs/reference/fidl/bindings/go-bindings.md
-- title: "Other languages"
-  path: /docs/reference/fidl/bindings/bindings-spec.md
diff --git a/docs/reference/fidl/bindings/bindings-spec.md b/docs/reference/fidl/bindings/bindings-spec.md
deleted file mode 100644
index d4af0af..0000000
--- a/docs/reference/fidl/bindings/bindings-spec.md
+++ /dev/null
@@ -1,101 +0,0 @@
-# FIDL bindings specification
-
-This document is a specification of requirements on the Fuchsia Interface
-Definition Language (**FIDL**) bindings.
-
-In this document, the following keywords are to be interpreted as described in
-[RFC2119][RFC2119]: **MAY**, **MUST**, **MUST NOT**, **OPTIONAL**,
-**RECOMMENDED**, **REQUIRED**, **SHALL**, **SHALL NOT**, **SHOULD**,
-**SHOULD NOT**.
-
-## Requirements
-
-Items described in this section **MUST** be met for bindings to be considered
-conformant.
-
-### Generated Code Indication
-
-A comment must be placed at the top of machine-generated code to indicate it is
-machine generated.
-For languages with a standard on how to indicate generated sources (as opposed
-to human-written code), that standard must be followed..
-
-In [Go][go-generated-code-comment] for instance, generated sources must be marked
-with a comment following the pattern
-
-```go
-// Code generated by <tool>; DO NOT EDIT.
-```
-
-## Recommendations
-
-Items described in this section **SHOULD** be met for bindings to be considered
-conformant.
-
-_TODO_
-
-## Best Practices
-
-Items described in this section **MAY** be met for bindings to be considered
-conformant.
-
-### Bits Support
-
-It is RECOMMENDED to support the following operators over generated values:
-
-* bitwise and, i.e `&`
-* bitwise or, i.e `|`
-* bitwise exclusive-or, i.e `^`
-* bitwise not, i.e `~`
-
-To provide bitwise operations which always result in valid bits values,
-implementations of bitwise not should further mask the resulting value with
-the mask of all values. In pseudo code:
-
-```
-~value1   means   mask & ~bits_of(value1)
-```
-
-This mask value is provided in the [JSON IR][jsonir] for convenience.
-
-Bindings SHOULD NOT support other operators since they could result in
-invalid bits value (or risk a non-obvious translation of their meaning), e.g.:
-
-* bitwise shifts, i.e `<<` or `>>`
-* bitwise unsigned shift, i.e `>>>`
-
-### Union Support
-
-_This section applies to flexible unions as well as the soon to be deprecated
-unions_
-
-For languages without union types and literals for these, it is RECOMMENDED to
-support factory methods for constructing new unions given a value for
-one of the possible variants. For example, in a C like language, this would
-allow replacing code like:
-
-```C
-my_union_t foo;
-foo.set_variant(bar);
-do_stuff(foo);
-```
-
-with something like:
-
-```C
-do_stuff(my_union_with_variant(bar));
-```
-
-Examples of this for the
-[HLCPP](https://fuchsia-review.googlesource.com/c/fuchsia/+/309246/) and
-[Go](https://fuchsia-review.googlesource.com/c/fuchsia/+/313205/) bindings.
-
-## Related Documents
-
-* [FTP-024: Mandatory Source Compatibility][ftp024]
-
-<!-- xrefs -->
-[jsonir]: /docs/reference/fidl/language/json-ir.md
-[ftp024]: /docs/contribute/governance/fidl/ftp/ftp-024.md
-[RFC2119]: https://tools.ietf.org/html/rfc2119
-[go-generated-code-comment]: https://github.com/golang/go/issues/13560#issuecomment-288457920
diff --git a/docs/reference/fidl/bindings/go-bindings.md b/docs/reference/fidl/bindings/go-bindings.md
index d4d3227..db3ceeb 100644
--- a/docs/reference/fidl/bindings/go-bindings.md
+++ b/docs/reference/fidl/bindings/go-bindings.md
@@ -264,6 +264,7 @@
 ```
 
 `User` provides the following methods:
+
 * `func (u *User) HasAge() bool` and `func (u *User) HasName() bool`: Checks for
   the presence of a field.
 * `func (u *User) SetAge(age uint8)` and `func (u *User) SetName(name string)`:
diff --git a/docs/reference/fidl/bindings/llcpp-bindings.md b/docs/reference/fidl/bindings/llcpp-bindings.md
index c39e24d..ace4d4d 100644
--- a/docs/reference/fidl/bindings/llcpp-bindings.md
+++ b/docs/reference/fidl/bindings/llcpp-bindings.md
@@ -390,7 +390,7 @@
 * `ResultOf::MakeMove MakeMove(uint8_t row, uint8_t col)`: Owned variant of a
   two way method call, which takes the parameters as arguments and returns the
   `ResultOf` class.
-* `UnownedResultOf::MakeMove(fidl::BytePart _request_bufffer, uint8_t row,
+* `UnownedResultOf::MakeMove(fidl::BytePart _request_buffer, uint8_t row,
   uint8_t col, fidl::BytePart _response_buffer)`: Caller-allocated variant of a
   two way method, which takes in backing storage for the request buffer,
   followed by the request parameters, and finally backing storage for the
diff --git a/docs/reference/fidl/bindings/overview.md b/docs/reference/fidl/bindings/overview.md
index f994913..48eeee9 100644
--- a/docs/reference/fidl/bindings/overview.md
+++ b/docs/reference/fidl/bindings/overview.md
@@ -8,11 +8,7 @@
   * A reference guide to the code generated by the FIDL compiler from your `.fidl` files
   * Generated API documentation for FIDL libraries that are provided in each language
 
-This section also contains guidance for developing your own bindings in a language
-of choice - for details, see the [bindings spec][bindings-spec]
-
 <!-- xrefs -->
-[bindings-spec]: /docs/reference/fidl/bindings/bindings-spec.md
 [hlcpp-bindings]: /docs/reference/fidl/bindings/hlcpp-bindings.md
 [rust-bindings]: /docs/reference/fidl/bindings/rust-bindings.md
 [llcpp-bindings]: /docs/reference/fidl/bindings/llcpp-bindings.md
diff --git a/docs/reference/fidl/language/_toc.yaml b/docs/reference/fidl/language/_toc.yaml
index 59d1547..3377c3f 100644
--- a/docs/reference/fidl/language/_toc.yaml
+++ b/docs/reference/fidl/language/_toc.yaml
@@ -18,3 +18,5 @@
   path: /docs/reference/fidl/language/fidlc.md
 - title: "Lexicon"
   path: /docs/reference/fidl/language/lexicon.md
+- title: "Bindings spec"
+  path: /docs/reference/fidl/language/bindings-spec.md
diff --git a/docs/reference/fidl/language/bindings-spec.md b/docs/reference/fidl/language/bindings-spec.md
new file mode 100644
index 0000000..2c26567
--- /dev/null
+++ b/docs/reference/fidl/language/bindings-spec.md
@@ -0,0 +1,326 @@
+# FIDL bindings specification
+
+This document is a specification of Fuchsia Interface Definition Language
+(**FIDL**) bindings. It is meant to provide guidance and best practices for
+bindings authors, and recommend specific approaches for their ergonomic use.
+
+In this document, the following keywords are to be interpreted as described in
+[RFC2119][RFC2119]: **MAY**, **MUST**, **MUST NOT**, **OPTIONAL**,
+**RECOMMENDED**, **REQUIRED**, **SHALL**, **SHALL NOT**, **SHOULD**, **SHOULD
+NOT**.
+
+## Generated code indication
+
+A comment must be placed at the top of machine-generated code to indicate it is
+machine generated. For languages with a standard on how to indicate generated
+sources (as opposed to human-written code), that standard must be followed.
+
+In [Go][go-generated-code-comment] for instance, generated sources must be
+marked with a comment following the pattern
+
+```go
+// Code generated by <tool>; DO NOT EDIT.
+```
+
+## Scoping
+
+It is RECOMMENDED to namespace machine-generated code to avoid clashing with
+user-defined symbols. This can be implement using scoping constructs provided by
+the language, like namespaces in C++, modules in Rust, or packages in Go and
+Dart. If the generated scope can have a name, it SHOULD be named using
+components of the FIDL library name which contains the definitions for the
+generated code, which allows each FIDL library to exist in a unique scope. In
+cases where scoping is not possible and the namespace is shared, some processing
+of the generated names (see [Naming](#naming)) may be necessary.
+
+## Naming {#naming}
+
+In general, the names used in the generated code SHOULD match the names used in
+the FIDL definition. Possible exceptions are listed in the following sections.
+
+### Casing
+
+Casing changes SHOULD be made to fit the idiomatic style of the language (e.g.
+using snake_case or CamelCase). `fidlc` will ensure that identifier uniqueness
+is enforced taking into account potential casing differences (see [FTP 40][ftp040]).
+
+### Reserved keywords and name clashes
+
+The generated code MUST take into account the reserved keywords in the target
+language to avoid unexpected when a keyword from the target language is used in
+the FIDL definition. An example scheme would be to prefix conflicting names with
+an underscore `_` (assuming no keywords begin with an underscore).
+
+The generated code MUST avoid generating code that causes naming conflicts. For
+example, in a function whose parameters are generated based on a FIDL
+definition, it MUST be impossible for the names of the local variables in the
+generated to clash with possible generated names.
+
+## Native types
+
+It is RECOMMENDED that bindings use the most specific and ergonomic native types
+where possible when converting built-in FIDL types to native types in the target
+language. For example, the Dart bindings use `Int32List` to represent a
+`vector<int32>:N` and `array<int32>:N` rather than the more generic `List<int>`.
+
+## Generated types and values
+
+### Constant support
+
+Generated code MUST generate variables containing matching values for each
+`const` definition in the corresponding FIDL. These variables SHOULD be marked
+as immutable in languages that support this (e.g. `const` in C++, Rust, and Go,
+or `final` in Dart).
+
+### Bits support
+
+Bindings MUST provide generated values for each bits member. They MAY also
+generate values representing the bits with no flags set, as well as the bits
+with every flag set (the "bits mask"). These values SHOULD be scoped to each set
+of bits.
+
+It is RECOMMENDED to support the following operators over generated values:
+
+* bitwise and, i.e `&`
+* bitwise or, i.e `|`
+* bitwise exclusive-or, i.e `^`
+* bitwise not, i.e `~`
+
+To provide bitwise operations which always result in valid bits values,
+implementations of bitwise not should further mask the resulting value with the
+mask of all values. In pseudo code:
+
+```
+~value1   means   mask & ~bits_of(value1)
+```
+
+This mask value is provided in the [JSON IR][jsonir] for convenience.
+
+Bindings SHOULD NOT support other operators since they could result in invalid
+bits value (or risk a non-obvious translation of their meaning), e.g.:
+
+* bitwise shifts, i.e `<<` or `>>`
+* bitwise unsigned shift, i.e `>>>`
+
+For cases where the generated code includes a type wrapping the underlying
+numeric bits value, it SHOULD be possible to convert between the raw value and
+the wrapper type. It is RECOMMENDED for this conversion to be explicit.
+
+### Enum support
+
+Bindings MUST provide generated values for each enum member. These values SHOULD
+be scoped to each enum.
+
+For cases where the generated code includes a type wrapping the underlying
+numeric enum value, it SHOULD be possible to convert between the raw value and
+the wrapper type. It is RECOMMENDED for this conversion to be explicit.
+
+### Struct support
+
+Bindings MUST provide a type for each struct that supports the following
+operations:
+
+* Construction with explicit values for each member.
+* Reading and writing members.
+
+Bindings MAY support default values for structs. The default values are
+specified in the [JSON IR][jsonir].
+
+### Union support
+
+Bindings MUST provide a type for each union that supports the following
+operations:
+
+* Construction with an explicit variant set. It is NOT RECOMMENDED for bindings
+  to offer construction without a variant. This should be considered only for
+  performance reasons or due to limitations of the target language.
+* Reading/writing the variant of the union and the data associated with that
+  variant.
+
+For languages without union types or union value literals, it is RECOMMENDED to
+support factory methods for constructing new unions given a value for one of the
+possible variants. For example, in a C like language, this would allow replacing
+code like:
+
+```C
+my_union_t foo;
+foo.set_variant(bar);
+do_stuff(foo);
+```
+
+with something like:
+
+```C
+do_stuff(my_union_with_variant(bar));
+```
+
+These factory methods SHOULD be named as "[Type]-with-[Variant]", cased properly
+for the target language.
+
+Examples of this exist for the
+[HLCPP](https://fuchsia-review.googlesource.com/c/fuchsia/+/309246/) and
+[Go](https://fuchsia-review.googlesource.com/c/fuchsia/+/313205/) bindings.
+
+#### Flexible unions
+
+The bindings MUST succeed when decoding a flexible union with an unknown
+variant. These unknown unions MAY provide ways for the user to read the
+underlying raw bytes and handles of the payload or the unknown ordinal.
+Additionally, it is OPTIONAL for the bindings to support re-encoding the raw
+bytes and handles when sending a flexible union with an unknown variant.
+
+Generated code for unions MAY allow the user to read the underlying raw ordinal
+of the message.
+
+### Table support
+
+Bindings MUST provide a type for each table that supports the following
+operations:
+
+* Construction where specifying values for each member is optional.
+* Reading and writing each member, including checking whether a given member is
+  set. These SHOULD follow the naming scheme: `get_[member]`, `set_[member]`,
+  and `has_[member]`, cased properly for the target language.
+
+Bindings MAY support default values for tables. The default values are specified
+in the [JSON IR][jsonir].
+
+Bindings MAY provide constructors for tables that only require specifying values
+for fields that have a value. For example, in Rust this can be accomplished
+using the `::empty()` constructor along with struct update syntax. Supporting
+construction this ways allows users to write code that is robust against
+addition of new fields to the table.
+
+## Protocol support
+
+### Error types
+
+It is OPTIONAL that bindings provide some form of special support for protocol
+methods with an error type matching the idiomatic way errors are handled in the
+target language.
+
+For example, languages that provide some form of a "result" type (i.e. a union
+type that contains a "success" variant and an "error" variant), such as Rust's
+`result::Result`, or `fit::result` in C++ MAY provide automatic conversions to
+and from these types when receiving or sending method responses with an error
+type.
+
+Languages with exceptions can have the generated protocol method code optionally
+raise an exception corresponding to the error type.
+
+In cases where this is not possible, the generated code MAY provide convenience
+functions for responding directly with a successful response or error value, or
+for receiving an error type response, in order avoid boilerplate user code for
+initializing result unions.
+
+## Error handling
+
+Protocols MAY surface transport errors back to the user. Transport errors can be
+categorized as errors encountered when converting between the native type and
+the wire format data, or as errors from the underlying transport mechanism (for
+example, an error obtained from calling `zx_channel_write`). These errors MAY
+consist of the error status, as well as any other diagnostics information.
+
+### Attributes
+
+Bindings MUST support the following [attributes][attributes]:
+
+* `[Transitional]`
+
+## Best practices
+
+### Alternative output
+
+It is OPTIONAL for bindings to provide alternative output methods to the FIDL
+wire format.
+
+One type of output could be user-friendly debug printing for the generated
+types. For example, printing a value of the bits:
+
+```fidl
+bits Mode {
+  Read = 1;
+  Write = 2;
+};
+```
+
+could print the string `"Mode.Read | Mode.Write"` rather than the raw value
+`"0b11"`.
+
+Similar user-friendly printing can be implemented for each of the generated FIDL
+types.
+
+Another example of alternative output would be serializing FIDL values to JSON.
+Users SHOULD have the option to opt-in or out to this functionality in order to
+follow the principle of "only pay for what you use". An example of this is
+`dart_fidl_json`, which is implemented using `fidlmerge`.
+
+### Message memory allocation
+
+Bindings MAY provide the option for users to provide their own memory to use
+when sending or receiving messages, which allows the user to control memory
+allocation.
+
+### Wire format memory layout
+
+Bindings MAY have the in memory layout of the generated FIDL types match the
+wire format of the type. Doing this can in theory avoid extra copies, as the
+data can be used directly as the transactional message, or vice versa. In
+practice, sending a FIDL message may still involve a copying step where the
+components of a message are assembled into a contiguous chunk of memory (called
+"linearization"). The downside of such an approach is that it makes the bindings
+more rigid: changes to the FIDL wire format become more complex to implement.
+
+The [LLCPP bindings][llcpp-tutorial] are the only binding which take this
+approach.
+
+### Equality comparison
+
+For aggregate types such as structs, tables, and unions, bindings MAY provide
+equality operators that perform a deep comparison on two instances of the same
+type. These operators SHOULD NOT be provided for resource types (see FTP-057) as
+comparison of handles is not possible. Avoiding exposing equality operators for
+resource types prevents source breakages caused by an equality operation
+'disappearing' when a handle is added to the type.
+
+### Copying
+
+For aggregate types such as structs, tables, and unions, bindings MAY provide
+functionality for copying instances of these types. Copying SHOULD NOT be
+provided for resource types (see [FTP-057][ftp057]) as making copies of handles
+is not guaranteed to succeed. Avoiding exposing copy operators for resource
+types prevents source breakages caused by a copy operation 'disappearing' or
+having its signature change when a handle is added to the type.
+
+### Test utilities
+
+It is OPTIONAL for bindings to generate additional code specifically to be used
+during testing. For example, the bindings can generate stub implementations of
+each protocol so that users only need too verride specific methods that are
+going to be exercised in a test.
+
+### Epitaphs
+
+Bindings SHOULD provide support for epitaphs, i.e. generated code that allows
+servers to send epitaphs and clients to receive and handle epitaphs.
+
+### Setters and Getters
+
+Bindings MAY provide setters and getters for fields on aggregate types (structs,
+unions, and tables). Even in languages where getter/setter methods are
+un-idiomatic, using these methods will allow renaming internal field names
+without breaking usages of that field.
+
+## Related Documents
+
+* [FTP-024: Mandatory Source Compatibility][ftp024]
+
+<!-- xrefs -->
+[jsonir]: /docs/reference/fidl/language/json-ir.md
+[ftp024]: /docs/contribute/governance/fidl/ftp/ftp-024.md
+[ftp040]: /docs/contribute/governance/fidl/ftp/ftp-040.md
+[ftp057]: /docs/contribute/governance/fidl/ftp/ftp-057.md
+[RFC2119]: https://tools.ietf.org/html/rfc2119
+[go-generated-code-comment]: https://github.com/golang/go/issues/13560#issuecomment-288457920
+[attributes]: /docs/reference/fidl/language/attributes.md
+[llcpp-tutorial]: /docs/development/languages/fidl/tutorials/tutorial-llcpp.md