Reorganize/rewrite the Mojom IDL intro.

I copied the old intro/outline to mojom_lang/mojom_lang.md (to
reorganize later -- it should be reference-ish in nature). And I made
intro/mojom_idl.md a briefer (and less formal) overview of (some of) the
more important points about Mojom IDL.

(Still left to write for intro/mojom_idl.md: stuff about consts and
annotations.)

R=vardhan@google.com

Review URL: https://codereview.chromium.org/1769863003 .
diff --git a/docs/intro/mojom_idl.md b/docs/intro/mojom_idl.md
index 8b49b67..f861e4c 100644
--- a/docs/intro/mojom_idl.md
+++ b/docs/intro/mojom_idl.md
@@ -1,17 +1,79 @@
 # Mojom IDL
 
 The Mojom IDL (interface definition language) is primarily used to describe
-*interfaces* to be used on [message pipes](message_pipes.md). Below, we describe
-practical aspects of the Mojom language. Elsewhere, we describe the [Mojom
-protocol](mojom_protocol.md). (**TODO(vtl)**: Also, serialization format?
-Versioning?)
+*interfaces* to be used on [message pipes](message_pipes.md). Below, we give a
+brief overview of some practical aspects of the Mojom language (for more
+details, see the [Mojom language](../mojom_lang/mojom_lang.md). Elsewhere, we
+describe the [Mojom protocol](mojom_protocol.md). (**TODO(vtl)**: Also,
+serialization format? Versioning?)
 
 Text files written in Mojom IDL are given the `.mojom` extension by convention
-(and are usually referred to as Mojom/mojom/`.mojom` files). The Mojom bindings
-generator (**TODO(vtl)**: link?) may be used to generate code in a variety of
-languages (including C++, Dart, and Go) from a Mojom file. Such generated code
-"implements" the things specified in the Mojom file, in a way that's appropriate
-for the particular target language.
+(and are usually referred to as Mojom/mojom/`.mojom` files). Mojom IDL permits
+C++-style comments: single-line comments starting with `//` or multi-line
+comments enclosed by `/* ... */`.
+
+The Mojom bindings generator (**TODO(vtl)**: link?) may be used to generate code
+in a variety of languages (including C++, Dart, and Go) from a Mojom file. Such
+generated code "implements" the things specified in the Mojom file, in a way
+that's appropriate for the particular target language.
+
+## Modules and imports
+
+A Mojom file begins with an optional *module* declaration, which acts like a C++
+namespace declaration (applying to the entire file). It is then followed by zero
+or more *import* statements, which make the contents of the imported files (and,
+transitively, their imports) available in the current file. For example:
+```mojom
+module my_module.my_submodule;
+
+import "path/to/another.mojom";
+import "path/to/yet/a/different.mojom";
+```
+
+### Name resolution
+
+Name resolution is basically C++-like (with `.` instead of `::`): Within
+`my_module.my_submodule`, an unnested declaration of a name `Foo` declares
+something with "full" name `my_module.my_submodule.Foo`. A *use* of a name `Foo`
+could either refer to one of the "full" names: `my_module.my_submodule.Foo`,
+`my_module.Foo`, or `Foo` (searched in that order).
+
+Nested declarations act in the expected way. E.g., if `Foo` is a struct
+containing an enum declaration of `Bar`, then `Foo.Bar` (or
+`my_submodule.Foo.Bar`, or `my_module.my_submodule.Foo.Bar`) can be used to
+refer to that enum outside of `Foo`.
+
+### Names and ordinals
+
+Generally, at a binary (as opposed to source) level, names in Mojom are not
+important (except in that they must not collide). Names may be changed without
+affecting binary compatibility.
+
+Instead, what's important are *ordinals*, which apply to struct fields
+(including message request/response parameters) and interface messages. Often,
+these are left implicit, in which case ordinals are assigned consecutively
+starting from 0. (Obviously, with implicit declaration, the order of declaration
+of struct fields, etc. is important.) Ordinals may also be assigned explicitly,
+using the notation `@123` (for example). (This allows struct fields, etc. to be
+re-ordered in a Mojom file without breaking binary compatibility.
+
+Though ordinals are important for evolving Mojom files in a backwards-compatible
+way, we will not discuss them in this introduction.
+
+### Naming style
+
+Though names are not important, various code generators expect names in a
+certain *style*, in order to transform them into a style more appropriate for a
+given target language:
+* `StudlyCaps` (a.k.a. `CapitalizedCamelCase`) for: (struct, interface, union,
+  and enum) type names and message (a.k.a. function or method) names;
+* `unix_hacker_style` for field names (in structs and unions) and "parameter"
+  names;
+* `ALL_CAPS_UNIX_HACKER_STYLE` for enum value names; and
+* `kStudlyCaps` for const names.
+
+Following this style is highly recommended (and may be required as a practical
+matter).
 
 ## Interfaces
 
@@ -68,234 +130,208 @@
   string b;
 };
 ```
-We will discuss in greater detail how structs are declared later.
+Structs (and interfaces) may also contain enum and const declarations, which
+we will discuss below.
 
-### Names in Mojom
+## Types
 
-Names in Mojom are not important. Except in affecting compatibility at the level
-of source code (when generating bindings), names in a Mojom file may be changed
-arbitrarily without any effect on the "meaning" of the Mojom file (subject to
-basic language requirements, e.g., avoiding collisions with keywords and other
-names). E.g., the following is completely equivalent to the interface discussed
-above:
+### Non-reference (simple and enum) types
+
+We have seen some simple types above, namely `int32`, `uint32`, and `bool`. A
+complete list of *simple* types is:
+* `bool`: boolean values;
+* `int8`, `int16`, `int32`, `int64`: signed 2's-complement integers of the given
+  size;
+* `uint8`, `uint16`, `uint32`, `uint64`: unsigned integers of the given size;
+  and
+* `float`, `double`: single- and double-precision IEEE floating-point numbers.
+
+Additionally, there are *enum* types, which are user-defined. Internally, enums
+are signed 2's complement 32-bit integers, so their values are restricted to
+that range. For example:
 ```mojom
-interface Something {
-  One(int32 an_integer, string a_string);
-  Two() => (bool a_boolean, uint32 an_unsigned);
-  Three() => ();
-};
-```
-The `Something` interface is compatible at a binary level with `MyInterface`. A
-client using the `Something` interface may communicate with a server
-implementing the `MyInterface` with no issues, and vice versa.
-
-The reason for this is that elements (messages, parameters, struct members,
-etc.) are actually identified by *ordinal* value. They may be specified
-explicitly (using `@123` notation; see below). If they are not specified
-explicitly, they are automatically assigned. (The ordinal values for each
-interface/struct/etc. must assign distinct values for each item, in a
-consecutive range starting at 0.)
-
-Explicitly assigning ordinals allows Mojom files to be rearranged "physically"
-without changing their meaning. E.g., perhaps one would write:
-```mojom
-interface MyInterface {
-  Bar@1() => (bool x@0, uint32 y@1);
-  Baz@2() => ();
-
-  // Please don't use this in new code!
-  FooDeprecated@0(int32 a@0, string b@1);
-};
-```
-
-Ordinals also tie into the versioning scheme (**TODO(vtl)**: link?), which
-allows Mojom files to be evolved in a backwards-compatible way. We will not
-discuss this matter further here.
-
-**TODO(vtl)**: Maybe mention exceptions to this in attributes (e.g.,
-`ServiceName`).
-
-## Mojom files
-
-A Mojom file consists of, in order:
-* an optional *module* declaration;
-* zero or more *import* statements (the order of these is not important); and
-* zero or more declarations of *struct*s, *interface*s, *union*s, *enum*s, or
-  *const*s (the order of these is not important).
-(These are all described further below.)
-
-Additionally, C/C++-style comments are supported (i.e., single-line comments
-starting with `//` or multi-line comments of the form `/* ... */`).
-
-As stated above, the order of struct/interface/union/enum/const declarations is
-not important. This is required to allow "cyclic" structures to be defined.
-Nonetheless, whenever possible, one should declare things before they are
-"used". For example, the following is valid but not recommended:
-```mojom
-// NOT recommended.
-
-const MyEnum kMyConst = kMyOtherConst;
-const MyEnum kMyOtherConst = A_VALUE;
-
 enum MyEnum {
-  A_VALUE,
-  ANOTHER_VALUE,
+  ONE_VALUE = 1,
+  ANOTHER_VALUE = -5,
+  THIRD_VALUE,  // Implicit value of -5 + 1 = -4.
+  A_DUPLICATE_VALUE = THIRD_VALUE,
 };
 ```
-
-### Naming style
-
-There is a standard style for naming things:
-* `StudlyCaps` (a.k.a. `CapitalizedCamelCase`) for: (struct, interface, union,
-  and enum) type names and message (a.k.a. function or method) names;
-* `unix_hacker_style` for field names (in structs and unions) and "parameter"
-  names;
-* `ALL_CAPS_UNIX_HACKER_STYLE` for enum value names; and
-* `kStudlyCaps` for const names.
-
-Following this style is highly recommended, since code generators for various
-languages will expect this style, in order to transform the names into a more
-language-appropriate style.
-
-### Module statement
-
-The Mojom *module* statement is just a way of logically grouping Mojom
-declarations. For example:
+Such an enum type may be used in a struct. For example:
 ```mojom
-module my_module;
+struct AStruct {
+  MyEnum x;
+  double y;
+};
 ```
-Mojom modules are similar to C++ namespaces (and the standard C++ code generator
-would put generated code into the `my_module` namespace), in that there is no
-implication that the file contains the entirety of the "module" definiton;
-multiple files may have the same module statement. (There is also no requirement
-that the module name have anything to do with the file path containing the Mojom
-file.)
+(As previously mentioned, an enum declaration may be nested inside a struct or
+interface declaration.)
 
-Mojom module names are hierarchical in that they can be composed of multiple
-parts separated by `.`. For example:
+Together, the simple and enum types comprise the *non-reference* types. The
+remaining types the *reference* types: *pointer* types and *handle* types.
+Unlike the non-reference types, the reference types all have some notion of
+"null".
+
+### Pointer types
+
+A struct is itself a pointer type, and can be used as a member of another struct
+(or as a request/response parameter, for that matter). For example:
 ```mojom
-module my_module.my_submodule;
-
 struct MyStruct {
+  int32 a;
+  string b;
+};
+
+struct MySecondStruct {
+  MyStruct x;
+  MyStruct? y;
 };
 ```
-Name look-up is similar to C++: E.g., if the current module is
-`my_module.my_submodule` then `MyStruct`, `my_submodule.MyStruct`, and
-`my_module.my_submodule.MyStruct` all refer to the above struct, whereas if the
-current module is just `my_module` then only the latter two do.
+Here, `x` is a *non-nullable* (i.e., required) field of `MySecondStruct`,
+whereas `y` is *nullable* (i.e., optional).
 
-### Import declarations
-
-An *import* declaration makes the declarations from another Mojom file available
-in the current Mojom file. Moreover, it operates transitively, in the sense that
-it also makes the imports of the imported file available, etc. The "argument" to
-the import statement is a path to a file. Tools that work with Mojom files are
-typically provided with a search path for importing files (just as a C++
-compiler can be provided with an "include path"), for the purposes of resolving
-these paths. (**TODO(vtl)**: This always includes the current Mojom file's path,
-right? Is the current path the first path that's searched?)
-
-For example:
-```mojom
-module my_module;
-
-import "path/to/another.mojom";
-import "path/to/yet/a/different.mojom";
-```
-This makes the contents of the two mentioned Mojom files available, together
-with whatever they import, transitively. (Note that names are resolved in the
-way described in the previous section.)
-
-Import cycles are not permitted (so, e.g., it would be an error if
-`path/to/another.mojom` imported the current Mojom file). However, it is
-entirely valid for Mojom files to be imported (transitively) multiple times
-(e.g., it is fine for `path/to/another.mojom` to also import
-`path/to/yet/a/different.mojom`).
-
-### Struct declarations
-
-A Mojom *struct* declaration consists of a finite sequence of *field
-declaration*, each of which consists of a *type*, a *name*, and optionally a
-*default value* (if applicable for the given type). (If no default value is
-declared, then the default is the default value for the field type, typically 0,
-null, or similar.)
-
-Additionally, a struct may contain enum and const declarations (**TODO(vtl)**:
-why not struct/union/interface declarations?). While the order of the field
-declarations (with respect to one another) is important, the ordering of the
-enum/const declarations (with respect to both the field declarations and other
-enum/const declarations) is not. (But as before, we recommend declaring things
-before "use".)
-
-Here is an example with these elements:
-```mojom
-struct Foo {
-  const int8 kSomeConstant = 123;
-
-  enum MyEnum {
-    A_VALUE,
-    ANOTHER_VALUE
-  };
-
-  int8 first_field = kSomeConstant;
-  uint32 second_field = 123;
-  MyEnum etc_etc = A_VALUE;
-  float a;    // Default value is 0.
-  string? b;  // Default value is null.
-};
-```
-(Note that `kSomeConstant` may be referred to as `Foo.kSomeConstant` and,
-similarly, `MyEnum` as `Foo.MyEnum`. This is required outside of the `Foo`
-declaration.)
-
-### Interface declarations
-
-**TODO(vtl)**
-
-### Union declarations
-
-**TODO(vtl)**
-
-### Enum declarations
-
-**TODO(vtl)**
-
-### Const declarations
-
-**TODO(vtl)**
-
-**TODO(vtl)**: Write/(re)organize the sections below.
-
-## Data types
-
-### Primitive types
-
-#### Standard types
-
-#### Enum types
-
-### "Pointer" types
-
-#### Nullability
-
-#### Strings
-
-#### Maps
-
-#### Structs
-
-#### Arrays
+A complete list of pointer types is:
+* structs: structs, as discussed above;
+* `string`/`string?`: Unicode strings;
+* `array<Type>`/`array<Type>?`: variable-size arrays (a.k.a. vectors or lists)
+  of type "Type" (which may be any type);
+* `array<Type, n>`/`array<Type, n>?`: fixed-size arrays of type "Type" and size
+  "n";
+* `map<KeyType, ValueType>`/`map<KeyType, ValueType>?`: maps (a.k.a.
+  dictionaries) of key type "KeyType" (which may be any non-reference type or
+  `string`) and value type "ValueType" (which may be any type); and
+* unions: see below.
 
 #### Unions
 
+*Unions* are "tagged unions". Union declarations look like struct declarations,
+but with different meaning. For example:
+```mojom
+union MyUnion {
+  int32 a;
+  int32 b;
+  string c;
+};
+```
+An element of type `MyUnion` must contain either an `int32` (called `a`), an
+`int32` (called `b`), *or* a string called `c`. (Like for structs, `MyUnion z`
+indicates a non-nullable instance, and `MyUnion?` indicates a nullable instance;
+in the nullable case, `z` may either be null or it must contain one of `a`, `b`,
+or `c`.)
+
 ### Handle types
 
 #### Raw handle types
 
+There are the "raw" *handle* types corresponding to different [Mojo
+handle](handles.md) types, with mostly self-explanatory names: `handle` (any
+kind of Mojo handle), `handle<message_pipe>`, `handle<data_pipe_consumer>`,
+`handle<data_pipe_producer>`, and `handle<shared_buffer>`. These are used to
+indicate that a given message or struct contains the indicated type of Mojo
+handle (recall that messages sent on [Mojo message pipes](message_pipes.md) may
+contain handles in addition to simple data).
+
+Like the pointer types, these may also be nullable (e.g., `handle?`,
+`handle<message_pipe>?`, etc.), where "null" indicates that no handle is to be
+sent (and may be realized, e.g., as the invalid Mojo handle).
+
 #### Interface types
 
+We have already seen *interface* type declarations. In a message (or struct), it
+is just a message pipe (endpoint) handle. However, it promises that the *peer*
+implements the given interface. For example:
+```mojom
+interface MyFirstInterface {
+  Foo() => ();
+};
+
+interface MySecondInterface {
+  Bar(MyFirstInterface x);
+  Baz(MyFirstInterface& y);  // Interface request! See below.
+};
+```
+Here, a receiver of a `Bar` message is promised a message pipe handle on which
+it can send (request) messages from `MyFirstInterface` (and then possibly
+receive responses). I.e., on receiving a `Bar` message, it may then send `Foo`
+message on `x` (and then receive the response to `Foo`).
+
+Like other handle types, instances may be non-nullable or nullable (e.g.,
+`MyFirstInterface?`).
+
 #### Interface request types
 
-## Annotations
+*Interface request* types are very much like interface types, and also arise
+from interface type declarations. They are annotated by a trailing `&`: e.g.,
+`MyFirstInterface&` (or `MyFirstInterface&?` for the nullable version).
+
+In a message (or struct), an interface request is also just a message pipe
+handle. However, it is a promise/"request" that the given message pipe handle
+implement the given interface (in contrast with the peer implementing it).
+
+In the above example, the receiver of `Baz` also gets a message pipe handle.
+However, the receiver is expected to implement `MyFirstInterface` on it (or pass
+it to someone else who will do so). I.e., `Foo` may be *received* on `y` (and
+then the response sent on it).
 
 ## Pipelining
+
+We saw above that Mojom allows both "interfaces" and "interface requests" to be
+sent in messages. Consider the following interface:
+```mojom
+interface Foo {
+  // ...
+};
+
+interface FooFactory {
+  CreateFoo1() => (Foo foo);
+  CreateFoo2(Foo& foo_request);
+};
+```
+
+`CreateFoo1` and `CreateFoo2` are functionally very similar: in both cases, the
+sender will (eventually) be able to send `Foo` messages on some message pipe
+handle. However, there are some important differences.
+
+In the case of `CreateFoo1`, the sender is only able to do so upon receiving the
+response to `CreateFoo1`, since the message pipe handle to which `Foo` messages
+can be written is contained in the response message to `CreateFoo1`.
+
+For `CreateFoo2`, the operation is somewhat different. Before sending
+`CreateFoo2`, the sender creates a message pipe. This consists of two message
+pipe handles (for peer endpoints), which we'll call `foo` and `foo_request` (the
+latter of which will be sent in the `CreateFoo2` message). Since message pipes
+are asynchronous and buffered, the sender can start writing `Foo` messages to
+`foo` at any time, possibly even before `CreateFoo2` is sent! I.e., it can use
+`foo` without waiting for a response message. This is referred to as
+*pipelining*.
+
+Pipelining is typically more efficient, since it eliminates eliminating the need
+to wait for a response, and it is often more natural, since receiving the
+response often entails returning to the message loop. Thus this is generally the
+preferred pattern for "factories" as in the above example.
+
+The main caveat is that with pipelining, there is no flow control. The sender of
+`CreateFoo2` has no indication of when `foo` is actually "ready", though even in
+the case of `CreateFoo1` there is no real promise that the `foo` in the response
+is actually "ready". (This is perhaps an indication that flow control should be
+done on `Foo`, e.g., by having its messages have responses.)
+
+Relatedly, with pipelining, there is limited opportunity to send back
+information regarding `foo`. (E.g., the preferred method of signalling error is
+to simply close `foo_request`.) So if additional information is *needed* to make
+use of `foo`, perhaps the pattern of `CreateFoo1` is preferable, e.g.:
+```mojom
+  CreateFoo() => (Foo foo, NeededInfo info);
+```
+
+## Consts
+
+**TODO(vtl)**
+
+## Annotations
+
+**TODO(vtl)**
+
+## See also
+
+**TODO(vtl)**
diff --git a/docs/mojom_lang/mojom_lang.md b/docs/mojom_lang/mojom_lang.md
new file mode 100644
index 0000000..430f452
--- /dev/null
+++ b/docs/mojom_lang/mojom_lang.md
@@ -0,0 +1,303 @@
+**TODO(vtl)**: Reorganize this to be properly structured.
+
+# Mojom IDL
+
+The Mojom IDL (interface definition language) is primarily used to describe
+*interfaces* to be used on [message pipes](message_pipes.md). Below, we describe
+practical aspects of the Mojom language. Elsewhere, we describe the [Mojom
+protocol](mojom_protocol.md). (**TODO(vtl)**: Also, serialization format?
+Versioning?)
+
+Text files written in Mojom IDL are given the `.mojom` extension by convention
+(and are usually referred to as Mojom/mojom/`.mojom` files). The Mojom bindings
+generator (**TODO(vtl)**: link?) may be used to generate code in a variety of
+languages (including C++, Dart, and Go) from a Mojom file. Such generated code
+"implements" the things specified in the Mojom file, in a way that's appropriate
+for the particular target language.
+
+## Interfaces
+
+A Mojom *interface* is (typically) used to describe communication on a message
+pipe. Typically, message pipes are created with a particular interface in mind,
+with one endpoint designated the *client* (which sends *request* messages and
+receives *response* messages) and the other designed that *server* or *impl*
+(which receives request messages and sends response messages).
+
+For example, take the following Mojom interface declaration:
+```mojom
+interface MyInterface {
+  Foo(int32 a, string b);
+  Bar() => (bool x, uint32 y);
+  Baz() => ();
+};
+```
+This specifies a Mojom interface in which the client may send three types of
+messages, namely `Foo`, `Bar`, and `Baz` (see the note below about names in
+Mojom). The first does not have a response message defined, whereas the latter
+two do. Whenever the server receives a `Bar` or `Baz` message, it *must*
+(eventually) send a (single) corresponding response message.
+
+The `Foo` request message contains two pieces of data: a signed (two's
+complement) 32-bit integer called `a` and a Unicode string called `b`. On the
+"wire", the message basically consists of metadata and a (serialized) *struct*
+(see below) containing `a` and `b`.
+
+The `Bar` request message contains no data, so on the wire it's just metadata
+and an empty struct. It has a response message, containing a boolean value `x`
+and an unsigned 32-bit integer `y`, which on the wire consists of metadata and a
+struct with `x` and `y`. Each time the server receives a `Bar` message, it is
+supposed to (eventually) respond by sending the response message. (Note: The
+client may include as part of the request message's metadata an identifier for
+the request; the response's metadata will then include this identifier, allowing
+it to match responses to requests.)
+
+The `Baz` request message also contains no data. It requires a response, also
+containing no data. Note that even though the response has no data, a response
+message must nonetheless be sent, functioning as an "ack". (Thus this is
+different from not having a response, as was the case for `Foo`.)
+
+## Structs
+
+Mojom defines a way of serializing data structures (with the Mojom IDL providing
+a way of specifying those data structures). A Mojom *struct* is the basic unit
+of serialization. As we saw above, messages are basically just structs, with a
+small amount of additional metadata.
+
+Here is a simple example of a struct declaration:
+```mojom
+struct MyStruct {
+  int32 a;
+  string b;
+};
+```
+We will discuss in greater detail how structs are declared later.
+
+### Names in Mojom
+
+Names in Mojom are not important. Except in affecting compatibility at the level
+of source code (when generating bindings), names in a Mojom file may be changed
+arbitrarily without any effect on the "meaning" of the Mojom file (subject to
+basic language requirements, e.g., avoiding collisions with keywords and other
+names). E.g., the following is completely equivalent to the interface discussed
+above:
+```mojom
+interface Something {
+  One(int32 an_integer, string a_string);
+  Two() => (bool a_boolean, uint32 an_unsigned);
+  Three() => ();
+};
+```
+The `Something` interface is compatible at a binary level with `MyInterface`. A
+client using the `Something` interface may communicate with a server
+implementing the `MyInterface` with no issues, and vice versa.
+
+The reason for this is that elements (messages, parameters, struct members,
+etc.) are actually identified by *ordinal* value. They may be specified
+explicitly (using `@123` notation; see below). If they are not specified
+explicitly, they are automatically assigned. (The ordinal values for each
+interface/struct/etc. must assign distinct values for each item, in a
+consecutive range starting at 0.)
+
+Explicitly assigning ordinals allows Mojom files to be rearranged "physically"
+without changing their meaning. E.g., perhaps one would write:
+```mojom
+interface MyInterface {
+  Bar@1() => (bool x@0, uint32 y@1);
+  Baz@2() => ();
+
+  // Please don't use this in new code!
+  FooDeprecated@0(int32 a@0, string b@1);
+};
+```
+
+Ordinals also tie into the versioning scheme (**TODO(vtl)**: link?), which
+allows Mojom files to be evolved in a backwards-compatible way. We will not
+discuss this matter further here.
+
+**TODO(vtl)**: Maybe mention exceptions to this in attributes (e.g.,
+`ServiceName`).
+
+## Mojom files
+
+A Mojom file consists of, in order:
+* an optional *module* declaration;
+* zero or more *import* statements (the order of these is not important); and
+* zero or more declarations of *struct*s, *interface*s, *union*s, *enum*s, or
+  *const*s (the order of these is not important).
+(These are all described further below.)
+
+Additionally, C/C++-style comments are supported (i.e., single-line comments
+starting with `//` or multi-line comments of the form `/* ... */`).
+
+As stated above, the order of struct/interface/union/enum/const declarations is
+not important. This is required to allow "cyclic" structures to be defined.
+Nonetheless, whenever possible, one should declare things before they are
+"used". For example, the following is valid but not recommended:
+```mojom
+// NOT recommended.
+
+const MyEnum kMyConst = kMyOtherConst;
+const MyEnum kMyOtherConst = A_VALUE;
+
+enum MyEnum {
+  A_VALUE,
+  ANOTHER_VALUE,
+};
+```
+
+### Naming style
+
+There is a standard style for naming things:
+* `StudlyCaps` (a.k.a. `CapitalizedCamelCase`) for: (struct, interface, union,
+  and enum) type names and message (a.k.a. function or method) names;
+* `unix_hacker_style` for field names (in structs and unions) and "parameter"
+  names;
+* `ALL_CAPS_UNIX_HACKER_STYLE` for enum value names; and
+* `kStudlyCaps` for const names.
+
+Following this style is highly recommended, since code generators for various
+languages will expect this style, in order to transform the names into a more
+language-appropriate style.
+
+### Module statement
+
+The Mojom *module* statement is just a way of logically grouping Mojom
+declarations. For example:
+```mojom
+module my_module;
+```
+Mojom modules are similar to C++ namespaces (and the standard C++ code generator
+would put generated code into the `my_module` namespace), in that there is no
+implication that the file contains the entirety of the "module" definiton;
+multiple files may have the same module statement. (There is also no requirement
+that the module name have anything to do with the file path containing the Mojom
+file.)
+
+Mojom module names are hierarchical in that they can be composed of multiple
+parts separated by `.`. For example:
+```mojom
+module my_module.my_submodule;
+
+struct MyStruct {
+};
+```
+Name look-up is similar to C++: E.g., if the current module is
+`my_module.my_submodule` then `MyStruct`, `my_submodule.MyStruct`, and
+`my_module.my_submodule.MyStruct` all refer to the above struct, whereas if the
+current module is just `my_module` then only the latter two do.
+
+### Import declarations
+
+An *import* declaration makes the declarations from another Mojom file available
+in the current Mojom file. Moreover, it operates transitively, in the sense that
+it also makes the imports of the imported file available, etc. The "argument" to
+the import statement is a path to a file. Tools that work with Mojom files are
+typically provided with a search path for importing files (just as a C++
+compiler can be provided with an "include path"), for the purposes of resolving
+these paths. (**TODO(vtl)**: This always includes the current Mojom file's path,
+right? Is the current path the first path that's searched?)
+
+For example:
+```mojom
+module my_module;
+
+import "path/to/another.mojom";
+import "path/to/yet/a/different.mojom";
+```
+This makes the contents of the two mentioned Mojom files available, together
+with whatever they import, transitively. (Note that names are resolved in the
+way described in the previous section.)
+
+Import cycles are not permitted (so, e.g., it would be an error if
+`path/to/another.mojom` imported the current Mojom file). However, it is
+entirely valid for Mojom files to be imported (transitively) multiple times
+(e.g., it is fine for `path/to/another.mojom` to also import
+`path/to/yet/a/different.mojom`).
+
+### Struct declarations
+
+A Mojom *struct* declaration consists of a finite sequence of *field
+declaration*, each of which consists of a *type*, a *name*, and optionally a
+*default value* (if applicable for the given type). (If no default value is
+declared, then the default is the default value for the field type, typically 0,
+null, or similar.)
+
+Additionally, a struct may contain enum and const declarations (**TODO(vtl)**:
+why not struct/union/interface declarations?). While the order of the field
+declarations (with respect to one another) is important, the ordering of the
+enum/const declarations (with respect to both the field declarations and other
+enum/const declarations) is not. (But as before, we recommend declaring things
+before "use".)
+
+Here is an example with these elements:
+```mojom
+struct Foo {
+  const int8 kSomeConstant = 123;
+
+  enum MyEnum {
+    A_VALUE,
+    ANOTHER_VALUE
+  };
+
+  int8 first_field = kSomeConstant;
+  uint32 second_field = 123;
+  MyEnum etc_etc = A_VALUE;
+  float a;    // Default value is 0.
+  string? b;  // Default value is null.
+};
+```
+(Note that `kSomeConstant` may be referred to as `Foo.kSomeConstant` and,
+similarly, `MyEnum` as `Foo.MyEnum`. This is required outside of the `Foo`
+declaration.)
+
+### Interface declarations
+
+**TODO(vtl)**
+
+### Union declarations
+
+**TODO(vtl)**
+
+### Enum declarations
+
+**TODO(vtl)**
+
+### Const declarations
+
+**TODO(vtl)**
+
+**TODO(vtl)**: Write/(re)organize the sections below.
+
+## Data types
+
+### Primitive types
+
+#### Standard types
+
+#### Enum types
+
+### "Pointer" types
+
+#### Nullability
+
+#### Strings
+
+#### Maps
+
+#### Structs
+
+#### Arrays
+
+#### Unions
+
+### Handle types
+
+#### Raw handle types
+
+#### Interface types
+
+#### Interface request types
+
+## Annotations
+
+## Pipelining