File indexing completed on 2025-01-31 10:12:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef GOOGLE_PROTOBUF_UTIL_FIELD_MASK_UTIL_H__
0011 #define GOOGLE_PROTOBUF_UTIL_FIELD_MASK_UTIL_H__
0012
0013 #include <cstdint>
0014 #include <string>
0015 #include <vector>
0016
0017 #include "google/protobuf/field_mask.pb.h"
0018 #include "absl/log/absl_check.h"
0019 #include "absl/strings/string_view.h"
0020 #include "google/protobuf/descriptor.h"
0021
0022
0023 #include "google/protobuf/port_def.inc"
0024
0025 namespace google {
0026 namespace protobuf {
0027 namespace util {
0028
0029 class PROTOBUF_EXPORT FieldMaskUtil {
0030 typedef google::protobuf::FieldMask FieldMask;
0031
0032 public:
0033
0034
0035 static std::string ToString(const FieldMask& mask);
0036 static void FromString(absl::string_view str, FieldMask* out);
0037
0038
0039
0040 template <typename T>
0041 static void FromFieldNumbers(const std::vector<int64_t>& field_numbers,
0042 FieldMask* out) {
0043 for (const auto field_number : field_numbers) {
0044 const FieldDescriptor* field_desc =
0045 T::descriptor()->FindFieldByNumber(field_number);
0046 ABSL_CHECK(field_desc != nullptr)
0047 << "Invalid field number for " << T::descriptor()->full_name() << ": "
0048 << field_number;
0049 AddPathToFieldMask<T>(field_desc->lowercase_name(), out);
0050 }
0051 }
0052
0053
0054
0055
0056
0057 static bool ToJsonString(const FieldMask& mask, std::string* out);
0058 static bool FromJsonString(absl::string_view str, FieldMask* out);
0059
0060
0061
0062
0063
0064 static bool GetFieldDescriptors(
0065 const Descriptor* descriptor, absl::string_view path,
0066 std::vector<const FieldDescriptor*>* field_descriptors);
0067
0068
0069 template <typename T>
0070 static bool IsValidPath(absl::string_view path) {
0071 return GetFieldDescriptors(T::descriptor(), path, nullptr);
0072 }
0073
0074
0075 template <typename T>
0076 static bool IsValidFieldMask(const FieldMask& mask) {
0077 for (int i = 0; i < mask.paths_size(); ++i) {
0078 if (!GetFieldDescriptors(T::descriptor(), mask.paths(i), nullptr)) {
0079 return false;
0080 }
0081 }
0082 return true;
0083 }
0084
0085
0086
0087 template <typename T>
0088 static void AddPathToFieldMask(absl::string_view path, FieldMask* mask) {
0089 ABSL_CHECK(IsValidPath<T>(path)) << path;
0090 mask->add_paths(std::string(path));
0091 }
0092
0093
0094
0095 template <typename T>
0096 static FieldMask GetFieldMaskForAllFields() {
0097 FieldMask out;
0098 GetFieldMaskForAllFields(T::descriptor(), &out);
0099 return out;
0100 }
0101 template <typename T>
0102 [[deprecated("Use *out = GetFieldMaskForAllFields() instead")]] static void
0103 GetFieldMaskForAllFields(FieldMask* out) {
0104 GetFieldMaskForAllFields(T::descriptor(), out);
0105 }
0106
0107
0108 static void GetFieldMaskForAllFields(const Descriptor* descriptor,
0109 FieldMask* out);
0110
0111
0112
0113
0114
0115
0116 static void ToCanonicalForm(const FieldMask& mask, FieldMask* out);
0117
0118
0119 static void Union(const FieldMask& mask1, const FieldMask& mask2,
0120 FieldMask* out);
0121
0122
0123 static void Intersect(const FieldMask& mask1, const FieldMask& mask2,
0124 FieldMask* out);
0125
0126
0127 template <typename T>
0128 static void Subtract(const FieldMask& mask1, const FieldMask& mask2,
0129 FieldMask* out) {
0130 Subtract(T::descriptor(), mask1, mask2, out);
0131 }
0132
0133
0134 static void Subtract(const Descriptor* descriptor, const FieldMask& mask1,
0135 const FieldMask& mask2, FieldMask* out);
0136
0137
0138
0139
0140
0141 static bool IsPathInFieldMask(absl::string_view path, const FieldMask& mask);
0142
0143 class MergeOptions;
0144
0145 static void MergeMessageTo(const Message& source, const FieldMask& mask,
0146 const MergeOptions& options, Message* destination);
0147
0148 class TrimOptions;
0149
0150
0151
0152 static bool TrimMessage(const FieldMask& mask, Message* message);
0153
0154
0155
0156
0157
0158 static bool TrimMessage(const FieldMask& mask, Message* message,
0159 const TrimOptions& options);
0160
0161 private:
0162 friend class SnakeCaseCamelCaseTest;
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176 static bool SnakeCaseToCamelCase(absl::string_view input,
0177 std::string* output);
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190 static bool CamelCaseToSnakeCase(absl::string_view input,
0191 std::string* output);
0192 };
0193
0194 class PROTOBUF_EXPORT FieldMaskUtil::MergeOptions {
0195 public:
0196 MergeOptions()
0197 : replace_message_fields_(false), replace_repeated_fields_(false) {}
0198
0199
0200
0201
0202
0203
0204 void set_replace_message_fields(bool value) {
0205 replace_message_fields_ = value;
0206 }
0207 bool replace_message_fields() const { return replace_message_fields_; }
0208
0209
0210
0211
0212 void set_replace_repeated_fields(bool value) {
0213 replace_repeated_fields_ = value;
0214 }
0215 bool replace_repeated_fields() const { return replace_repeated_fields_; }
0216
0217 private:
0218 bool replace_message_fields_;
0219 bool replace_repeated_fields_;
0220 };
0221
0222 class PROTOBUF_EXPORT FieldMaskUtil::TrimOptions {
0223 public:
0224 TrimOptions() : keep_required_fields_(false) {}
0225
0226
0227
0228
0229 void set_keep_required_fields(bool value) { keep_required_fields_ = value; }
0230 bool keep_required_fields() const { return keep_required_fields_; }
0231
0232 private:
0233 bool keep_required_fields_;
0234 };
0235
0236 }
0237 }
0238 }
0239
0240 #include "google/protobuf/port_undef.inc"
0241
0242 #endif