pw_status: Docs update

- Expand status docs.
- Fix update_style.py docstring.

Change-Id: I44323ca293d801d9c8b5e24ee3353046ec3d5db2
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/19164
Reviewed-by: Ewout van Bekkum <ewout@google.com>
Reviewed-by: Alexei Frolov <frolv@google.com>
Commit-Queue: Wyatt Hepler <hepler@google.com>
diff --git a/pw_status/docs.rst b/pw_status/docs.rst
index ea09ec2..465c3d0 100644
--- a/pw_status/docs.rst
+++ b/pw_status/docs.rst
@@ -7,13 +7,212 @@
 ---------
 pw_status
 ---------
+``pw_status`` provides features for communicating the result of an operation.
+The classes in ``pw_status`` are used extensively throughout Pigweed.
+
+pw::Status
+==========
+The primary feature of ``pw_status`` is the ``pw::Status`` class.
 ``pw::Status`` (``pw_status/status.h``) is a simple, zero-overhead status
-object. It uses Google's standard status codes, which are also used by projects
-such as `gRPC <https://github.com/grpc/grpc/blob/master/doc/statuscodes.md>`_.
+object that wraps a status code.
 
+``pw::Status`` uses Google's standard status codes (see the `Google APIs
+repository <https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto>`_).
+These codes are used extensively in Google projects including `Abseil
+<https://abseil.io>`_ (`status/status.h
+<https://cs.opensource.google/abseil/abseil-cpp/+/master:absl/status/status.h>`_
+) and `gRPC <https://grpc.io>`_ (`doc/statuscodes.md
+<https://github.com/grpc/grpc/blob/master/doc/statuscodes.md>`_).
+
+A ``Status`` is created with a ``static constexpr`` member function
+corresponding to the code.
+
+.. code-block:: cpp
+
+  // Ok (gRPC code "OK") does not indicate an error; this value is returned on
+  // success. It is typical to check for this value before proceeding on any
+  // given call across an API or RPC boundary. To check this value, use the
+  // `Status::ok()` member function rather than inspecting the raw code.
+  Status::Ok()
+
+  // Cancelled (gRPC code "CANCELLED") indicates the operation was cancelled,
+  // typically by the caller.
+  Status::Cancelled()
+
+  // Unknown (gRPC code "UNKNOWN") indicates an unknown error occurred. In
+  // general, more specific errors should be raised, if possible. Errors raised
+  // by APIs that do not return enough error information may be converted to
+  // this error.
+  Status::Unknown()
+
+  // InvalidArgument (gRPC code "INVALID_ARGUMENT") indicates the caller
+  // specified an invalid argument, such a malformed filename. Note that such
+  // errors should be narrowly limited to indicate to the invalid nature of the
+  // arguments themselves. Errors with validly formed arguments that may cause
+  // errors with the state of the receiving system should be denoted with
+  // `FailedPrecondition` instead.
+  Status::InvalidArgument()
+
+  // DeadlineExceeded (gRPC code "DEADLINE_EXCEEDED") indicates a deadline
+  // expired before the operation could complete. For operations that may change
+  // state within a system, this error may be returned even if the operation has
+  // completed successfully. For example, a successful response from a server
+  // could have been delayed long enough for the deadline to expire.
+  Status::DeadlineExceeded()
+
+  // NotFound (gRPC code "NOT_FOUND") indicates some requested entity (such as
+  // a file or directory) was not found.
+  //
+  // `NotFound` is useful if a request should be denied for an entire class of
+  // users, such as during a gradual feature rollout or undocumented allow list.
+  // If, instead, a request should be denied for specific sets of users, such as
+  // through user-based access control, use `PermissionDenied` instead.
+  Status::NotFound()
+
+  // AlreadyExists (gRPC code "ALREADY_EXISTS") indicates the entity that a
+  // caller attempted to create (such as file or directory) is already present.
+  Status::AlreadyExists()
+
+  // PermissionDenied (gRPC code "PERMISSION_DENIED") indicates that the caller
+  // does not have permission to execute the specified operation. Note that this
+  // error is different than an error due to an *un*authenticated user. This
+  // error code does not imply the request is valid or the requested entity
+  // exists or satisfies any other pre-conditions.
+  //
+  // `PermissionDenied` must not be used for rejections caused by exhausting
+  // some resource. Instead, use `ResourceExhausted` for those errors.
+  // `PermissionDenied` must not be used if the caller cannot be identified.
+  // Instead, use `Unauthenticated` for those errors.
+  Status::PermissionDenied()
+
+  // ResourceExhausted (gRPC code "RESOURCE_EXHAUSTED") indicates some resource
+  // has been exhausted, perhaps a per-user quota, or perhaps the entire file
+  // system is out of space.
+  Status::ResourceExhausted()
+
+  // FailedPrecondition (gRPC code "FAILED_PRECONDITION") indicates that the
+  // operation was rejected because the system is not in a state required for
+  // the operation's execution. For example, a directory to be deleted may be
+  // non-empty, an "rmdir" operation is applied to a non-directory, etc.
+  //
+  // Some guidelines that may help a service implementer in deciding between
+  // `FailedPrecondition`, `Aborted`, and `Unavailable`:
+  //
+  //  (a) Use `Unavailable` if the client can retry just the failing call.
+  //  (b) Use `Aborted` if the client should retry at a higher transaction
+  //      level (such as when a client-specified test-and-set fails, indicating
+  //      the client should restart a read-modify-write sequence).
+  //  (c) Use `FailedPrecondition` if the client should not retry until
+  //      the system state has been explicitly fixed. For example, if an "rmdir"
+  //      fails because the directory is non-empty, `FailedPrecondition`
+  //      should be returned since the client should not retry unless
+  //      the files are deleted from the directory.
+  Status::FailedPrecondition()
+
+  // Aborted (gRPC code "ABORTED") indicates the operation was aborted,
+  // typically due to a concurrency issue such as a sequencer check failure or a
+  // failed transaction.
+  //
+  // See the guidelines above for deciding between `FailedPrecondition`,
+  // `Aborted`, and `Unavailable`.
+  Status::Aborted()
+
+  // OutOfRange (gRPC code "OUT_OF_RANGE") indicates the operation was
+  // attempted past the valid range, such as seeking or reading past an
+  // end-of-file.
+  //
+  // Unlike `InvalidArgument`, this error indicates a problem that may
+  // be fixed if the system state changes. For example, a 32-bit file
+  // system will generate `InvalidArgument` if asked to read at an
+  // offset that is not in the range [0,2^32-1], but it will generate
+  // `OutOfRange` if asked to read from an offset past the current
+  // file size.
+  //
+  // There is a fair bit of overlap between `FailedPrecondition` and
+  // `OutOfRange`.  We recommend using `OutOfRange` (the more specific
+  // error) when it applies so that callers who are iterating through
+  // a space can easily look for an `OutOfRange` error to detect when
+  // they are done.
+  Status::OutOfRange()
+
+  // Unimplemented (gRPC code "UNIMPLEMENTED") indicates the operation is not
+  // implemented or supported in this service. In this case, the operation
+  // should not be re-attempted.
+  Status::Unimplemented()
+
+  // Internal (gRPC code "INTERNAL") indicates an internal error has occurred
+  // and some invariants expected by the underlying system have not been
+  // satisfied. This error code is reserved for serious errors.
+  Status::Internal()
+
+  // Unavailable (gRPC code "UNAVAILABLE") indicates the service is currently
+  // unavailable and that this is most likely a transient condition. An error
+  // such as this can be corrected by retrying with a backoff scheme. Note that
+  // it is not always safe to retry non-idempotent operations.
+  //
+  // See the guidelines above for deciding between `FailedPrecondition`,
+  // `Aborted`, and `Unavailable`.
+  Status::Unavailable()
+
+  // DataLoss (gRPC code "DATA_LOSS") indicates that unrecoverable data loss or
+  // corruption has occurred. As this error is serious, proper alerting should
+  // be attached to errors such as this.
+  Status::DataLoss()
+
+  // Unauthenticated (gRPC code "UNAUTHENTICATED") indicates that the request
+  // does not have valid authentication credentials for the operation. Correct
+  // the authentication and try again.
+  Status::Unauthenticated()
+
+.. attention::
+
+  Some code may use all-caps status values such as ``Status::UNKNOWN`` instead
+  of ``Status::Unknown()``. These all-caps status codes are deprecated and will
+  be removed in the future. Do not use them; use the functions above instead.
+
+  The all-caps status aliases were deprecated because they do not comply with
+  the style guide and potentially conflict with macro definitions. For example,
+  projects might define an ``INTERNAL`` macro, which would prevent ``status.h``
+  or code that uses ``Status::INTERNAL`` from compiling.
+
+  The Python tool ``pw_status/update_style.py`` may be used to migrate code in a
+  Git repo to the new status style.
+
+C compatibility
+---------------
+``pw_status`` provides the C-compatible ``pw_Status`` enum for the status codes.
+For ease of use, ``pw::Status`` implicitly converts to and from ``pw_Status``.
+However, the ``pw_Status`` enum should never be used in C++; instead use the
+``Status`` class.
+
+The values of the ``pw_Status`` enum are all-caps and prefixed with
+``PW_STATUS_``. For example, ``PW_STATUS_DATA_LOSS`` corresponds with the C++
+``Status::DataLoss()``.
+
+StatusWithSize
+==============
 ``pw::StatusWithSize`` (``pw_status/status_with_size.h``) is a convenient,
-efficent class for reporting a status along with an unsigned integer value.
+efficient class for reporting a status along with an unsigned integer value.
+It is similar to the ``pw::Result<T>`` class, but it stores both a size and a
+status, regardless of the status value, and only supports a limited range (27
+bits).
 
+``pw::StatusWithSize`` values may be created with functions similar to
+``pw::Status``. For example,
+
+  .. code-block:: cpp
+
+    // An OK StatusWithSize with a size of 123.
+    StatusWithSize::Ok(123)
+
+    // A NOT_FOUND StatusWithSize with a size of 0.
+    StatusWithSize::NotFound()
+
+    // A RESOURCE_EXHAUSTED StatusWithSize with a size of 10.
+    StatusWithSize::ResourceExhausted(10)
+
+PW_TRY
+======
 ``PW_TRY`` (``pw_status/try.h``) is a convenient set of macros for working
 with Status and StatusWithSize objects in functions that return Status or
 StatusWithSize. The PW_TRY and PW_TRY_WITH_SIZE macros call a function and
@@ -51,8 +250,6 @@
     // following code executed if the PW_TRY_ASSIGN function above returns OK.
   }
 
-The classes in pw_status are used extensively by other Pigweed modules.
-
 Compatibility
 =============
 C++11
diff --git a/pw_status/py/pw_status/update_style.py b/pw_status/py/pw_status/update_style.py
index d7b642e..57c92bb 100755
--- a/pw_status/py/pw_status/update_style.py
+++ b/pw_status/py/pw_status/update_style.py
@@ -12,9 +12,9 @@
 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 # License for the specific language governing permissions and limitations under
 # the License.
-"""Decodes and detokenizes Base64-encoded strings in serial output.
+"""Updates pw::Status usages from Status::CODE to Status::Code() style.
 
-The output is printed or saved to a file. Input is not supported.
+Also updates StatusWithSize.
 """
 
 import argparse