SEBA-662 update xproto documentation
Change-Id: I7a6b812ac4c69c75533466442c3664f126a4af93
diff --git a/docs/dev/xproto.md b/docs/dev/xproto.md
index 8b10863..d50a941 100644
--- a/docs/dev/xproto.md
+++ b/docs/dev/xproto.md
@@ -144,7 +144,7 @@
by a particular model.
Currently supported model options include: `name`, `app_label`, `verbose_name`,
-`legacy`, `tosca_description`, `validators`, `plural`, `singular`, and
+`custom_python`, `tosca_description`, `validators`, `plural`, `singular`, and
`gui_hidden`.
The name option is a short name used to refer to your service. For example, in
@@ -169,16 +169,28 @@
option verbose_name = "Virtual Subscriber Gateway Service";
```
+The `custom_python` option allows custom code to be attached to model.
+
```protobuf
-option app_label = "legacy"
+option custom_python = "True"
```
-The legacy option is for services that require custom Python code in their
-generated models. Without this option set, for any given model (`VSGService`)
-the toolchain generates model classes in a self-contained file
-(`vsgservice.py`). With this option set, the toolchain generates the models in
-a file called `vsgservice_decl.py`. All of the models in this file have the
-suffix `_decl`. It is then up to the service developer to provide the final
+The `custom_python` option is for services that require custom Python code in their
+generated models. This option may either be specified at the file level and apply
+to all models within a file, or individually at the model level within a file.
+When custom python models are in use, the following changes occur to the generative
+toolchain,
+
+* Models are created in a file called "models_decl.py" (or modelname_decl.py depending
+ on whether you're working on a service or in the core).
+* Autogenerated models have the suffix `_decl` attached to them, for example
+ `VSGService_decl`.
+* If there's a mix of custom_python and non-custom_python models in the same file, then
+ the non-custom_python models will automatically receive stubs that convert them
+ from the `_decl` model to the non-`_decl` model.
+
+Once the developer has designated some models as having custom python, it is then
+up to the service developer to provide the final
models. The code below gives an example of custom models that inherit from such
intermediate `decl` models:
@@ -192,6 +204,16 @@
You can use the xproto `service_extender` target to generate a stub for your
final model definitions.
+> NOTE: As custom_python code ends up extending the XOS core with service-specific code,
+> it is recommended to avoid using custom_python if an alternative exists to achieve
+> the same functionality. For example, `model_policies` are another way to attach
+> service-specific features to models, and run in the synchronizer rather than in the
+> core.
+>
+> NOTE: The `custom_python` option was previously called `legacy`, and you may
+> still encounter some services that use the keyword `legacy` instead of
+> custom_python.
+
The plural and singular options provide the grammatically correct plural and
singular forms of your model name to ensure that autogenerated API endpoints
are valid.
@@ -273,6 +295,19 @@
option max_value = 100;
```
+Designates a field as `feedback_state`, by default preventing it from being updated using GUI
+or CLI tools.
+
+```protobuf
+option feedback_state = True;
+```
+
+Designates a field as `bookkeeping_state`, by default hiding it from GUI or CLI tools.
+
+```protobuf
+option bookkeeping_state = True;
+```
+
Do not display this field in the GUI (also available at the model level):
```protobuf
@@ -357,16 +392,22 @@
Field names use lower-case with underscores separating names. Examples of valid
field names are: name, `disk_format`, `controller_format`.
-### Declarative vs Feedback State
+### Declarative vs Feedback vs Bookkeeping State
By convention, the fields that make up a model are classified as holding one of
-two kinds of state: *declarative* and *feedback*.
+three kinds of state: *declarative*, *feedback*, or *bookkeeping*.
Fields set by the operator to specify (declare) the expected state of CORD's
underlying components are said to hold *declarative state*. In contrast,
fields that record operational data reported from CORD's underlying (backend)
components are said to hold *feedback state*.
+*bookkeeping state* are fields that are typically used by the synchronizer
+framework or by a synchronizer to hold information about the model that is
+useful to the synchronizer, but not to the operator. For example, timestamps
+that are used to track when models are dirty, error retry information,
+etc.
+
For more information about declarative and feedback state, and the role they
play in synchornizing the data model with the backend components, read about
the [Synchronizer Architecture](sync_arch.md).