• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2023 Google Inc.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 #ifndef GOOGLE_PROTOBUF_FEATURE_RESOLVER_H__
9 #define GOOGLE_PROTOBUF_FEATURE_RESOLVER_H__
10 
11 #include <memory>
12 #include <string>
13 #include <utility>
14 #include <vector>
15 
16 #include "absl/container/flat_hash_set.h"
17 #include "absl/status/status.h"
18 #include "absl/status/statusor.h"
19 #include "absl/strings/string_view.h"
20 #include "absl/types/span.h"
21 #include "google/protobuf/descriptor.h"
22 #include "google/protobuf/descriptor.pb.h"
23 #include "google/protobuf/dynamic_message.h"
24 
25 // Must be included last.
26 #include "google/protobuf/port_def.inc"
27 
28 namespace google {
29 namespace protobuf {
30 
31 // These helpers implement the unique behaviors of edition features.  For more
32 // details, see go/protobuf-editions-features.
33 class PROTOBUF_EXPORT FeatureResolver {
34  public:
35   FeatureResolver(FeatureResolver&&) = default;
36   FeatureResolver& operator=(FeatureResolver&&) = delete;
37 
38   // Compiles a set of FeatureSet extensions into a mapping of edition to unique
39   // defaults.  This is the most complicated part of feature resolution, and by
40   // abstracting this out into an intermediate message, we can make feature
41   // resolution significantly more portable.
42   static absl::StatusOr<FeatureSetDefaults> CompileDefaults(
43       const Descriptor* feature_set,
44       absl::Span<const FieldDescriptor* const> extensions,
45       Edition minimum_edition, Edition maximum_edition);
46 
47   // Creates a new FeatureResolver at a specific edition.  This calculates the
48   // default feature set for that edition, using the output of CompileDefaults.
49   static absl::StatusOr<FeatureResolver> Create(
50       Edition edition, const FeatureSetDefaults& defaults);
51 
52   // Creates a new feature set using inheritance and default behavior. This is
53   // designed to be called recursively, and the parent feature set is expected
54   // to be a fully merged one.  The returned FeatureSet will be fully resolved
55   // for any extensions that were used to construct the defaults.
56   absl::StatusOr<FeatureSet> MergeFeatures(
57       const FeatureSet& merged_parent, const FeatureSet& unmerged_child) const;
58 
59   // Validates an unresolved FeatureSet object to make sure they obey the
60   // lifetime requirements.  This needs to run *within* the pool being built, so
61   // that the descriptors of any feature extensions are known and can be
62   // validated.  `pool_descriptor` should point to the FeatureSet descriptor
63   // inside the pool, or nullptr if one doesn't exist,
64   //
65   // This will return error messages for any explicitly set features used before
66   // their introduction or after their removal.  Warnings will be included for
67   // any explicitly set features that have been deprecated.
68   struct ValidationResults {
69     std::vector<std::string> errors;
70     std::vector<std::string> warnings;
71   };
72   static ValidationResults ValidateFeatureLifetimes(
73       Edition edition, const FeatureSet& features,
74       const Descriptor* pool_descriptor);
75 
76  private:
FeatureResolver(FeatureSet defaults)77   explicit FeatureResolver(FeatureSet defaults)
78       : defaults_(std::move(defaults)) {}
79 
80   FeatureSet defaults_;
81 };
82 
83 }  // namespace protobuf
84 }  // namespace google
85 
86 #endif  // GOOGLE_PROTOBUF_FEATURE_RESOLVER_H__
87 
88 #include "google/protobuf/port_undef.inc"
89