go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/common/proto/msgpackpb/options.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 msgpackpb
    16  
    17  type options struct {
    18  	deterministic        bool
    19  	unknownFieldBehavior unknownFieldBehavior
    20  
    21  	internUnmarshalTable []string
    22  	internMarshalTable   map[string]uint
    23  }
    24  
    25  // Option allows modifying the behavior of Marshal and Unmarshal.
    26  type Option func(*options)
    27  
    28  // IgnoreUnknownFields is an Option which affects Marshal + Unmarshal.
    29  //
    30  // Marshal: Unknown msgpack fields on the proto message to be dropped
    31  // (non-msgpack unknown fields will result in an error).
    32  //
    33  // Unmarshal: Skips unknown fields, and do not store them on the decoded proto message.
    34  func IgnoreUnknownFields(o *options) {
    35  	o.unknownFieldBehavior = ignoreUnknownFields
    36  }
    37  
    38  // DisallowUnknownFields is an Option which affects Marshal + Unmarshal.
    39  //
    40  // Marshal: Return an error when encoding proto messages containing any unknown
    41  // fields.
    42  //
    43  // Unmarshal: Return an error when decoding messages containing unknown fields.
    44  func DisallowUnknownFields(o *options) {
    45  	o.unknownFieldBehavior = disallowUnknownFields
    46  }
    47  
    48  // Deterministic is an Option which affects Marshal.
    49  //
    50  // (Providing this to Unmarshal is an error).
    51  //
    52  // If set, the proto will be encoded with the following additional rules:
    53  //   - All fields will be output ordered by their field tag number.
    54  //   - Maps will sort keys (lexically or numerically)
    55  //   - Any unknown msgpack fields will (if PreserveUnknownFields was given when
    56  //     Unmarshalling) be interleaved with the known fields in order, sorting any
    57  //     messages or maps.
    58  func Deterministic(o *options) {
    59  	o.deterministic = true
    60  }
    61  
    62  // WithStringInternTable lets you set an optional string internment table; Any
    63  // strings encoded which are contained in this table will be replaced with an
    64  // integer denoting the index in this table where the string was found.
    65  //
    66  // This includes repeated strings, map keys, and string value fields.
    67  func WithStringInternTable(table []string) Option {
    68  	return func(o *options) {
    69  		o.internUnmarshalTable = table
    70  		o.internMarshalTable = make(map[string]uint, len(table))
    71  		for i, val := range table {
    72  			o.internMarshalTable[val] = uint(i)
    73  		}
    74  	}
    75  }
    76  
    77  type unknownFieldBehavior byte
    78  
    79  const (
    80  	preserveUnknownFields unknownFieldBehavior = iota
    81  	ignoreUnknownFields
    82  	disallowUnknownFields
    83  )