go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/common/proto/protowalk/doc.go (about)

     1  // Copyright 2022 The LUCI Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Package protowalk contains routines for efficiently walking proto messages,
    16  // focusing on the ability to react to field annotations.
    17  //
    18  // This package defines an interface (FieldProcessor) which you can
    19  // implement to react to any fields you like.
    20  //
    21  // This package also comes with stock implementations for the following common
    22  // field annotations:
    23  //   - google.api.field_behavior = REQUIRED
    24  //   - google.api.field_behavior = OUTPUT_ONLY
    25  //   - deprecated = true
    26  //
    27  // # How it works
    28  //
    29  // 1. Register a FieldProcessor using RegisterFieldProcessor.
    30  //
    31  // A FieldProcessor checks and/or manipulates fields in a proto message. When
    32  // registering an implementation, you also provide a `selector` function which
    33  // detects fields (e.g. by their type, field options, etc.) that the
    34  // FieldProcessor wants to operate on.
    35  //
    36  // 2. Use the Fields() with one or more FieldProcessor instantances to process
    37  // a proto message.
    38  //
    39  // Fields generates, once per process, a global cache entry keyed on
    40  // (msgType, processorType). This entry is a list of fields in `msgType`
    41  // which the FieldProcessor's registered `selector` function says it should
    42  // operate on, and also indicates for a given field if it should be recursed
    43  // for this processor (i.e. if field `M.a` is a message type `A` which has
    44  // fields that match this processor).
    45  //
    46  // Once the cache entries are generated, Fields then generates a 'plan' which is
    47  // the combination of _all_ the provided processors' cache entries, such that
    48  // Fields() can then walk through all affected fields, once, in order,
    49  // generating results from the provided message in an ordered and deterministic
    50  // fashion.
    51  //
    52  // The upshot is that Fields() should be O(CheckableFields), no matter how big
    53  // the proto messages are, rather than a naive O(Fields) implementation.
    54  //
    55  // A Result contains the ProtoPath and a message generated by the
    56  // FieldProcessor. The ProtoPath describes the path through the source message
    57  // to the affected field, and can either be printed for display, or can be used
    58  // to retrieve the actual value.
    59  package protowalk