xref: /aosp_15_r20/external/tink/cc/internal/parameters_parser.h (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2022 Google LLC
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 ////////////////////////////////////////////////////////////////////////////////
16 
17 #ifndef TINK_INTERNAL_PARAMETERS_PARSER_H_
18 #define TINK_INTERNAL_PARAMETERS_PARSER_H_
19 
20 #include <functional>
21 #include <memory>
22 #include <string>
23 #include <typeindex>
24 #include <utility>
25 
26 #include "absl/status/status.h"
27 #include "absl/strings/string_view.h"
28 #include "tink/internal/parser_index.h"
29 #include "tink/internal/serialization.h"
30 #include "tink/parameters.h"
31 #include "tink/util/status.h"
32 #include "tink/util/statusor.h"
33 
34 namespace crypto {
35 namespace tink {
36 namespace internal {
37 
38 // Non-template base class that can be used with internal registry map.
39 class ParametersParser {
40  public:
41   // Parses `serialization` into a parameters object.
42   //
43   // This function is usually called on a `Serialization` subclass matching the
44   // value returned by `ObjectIdentifier()`. However, implementations should
45   // verify that this is the case.
46   virtual util::StatusOr<std::unique_ptr<Parameters>> ParseParameters(
47       const Serialization& serialization) const = 0;
48 
49   // Returns the object identifier for `SerializationT`, which is only valid
50   // for the lifetime of this object.
51   //
52   // The object identifier is a unique identifier per registry for this object
53   // (in the standard proto serialization, it is the type URL). In other words,
54   // when registering a `ParametersParser`, the registry will invoke this to get
55   // the handled object identifier. In order to parse an object of
56   // `SerializationT`, the registry will then obtain the object identifier of
57   // this serialization object, and call the parser corresponding to this
58   // object.
59   virtual absl::string_view ObjectIdentifier() const = 0;
60 
61   // Returns an index that can be used to look up the `ParametersParser`
62   // object registered for the `ParametersT` type in a registry.
63   virtual ParserIndex Index() const = 0;
64 
65   virtual ~ParametersParser() = default;
66 };
67 
68 // Parses `SerializationT` objects into `ParametersT` objects.
69 template <typename SerializationT, typename ParametersT>
70 class ParametersParserImpl : public ParametersParser {
71  public:
ParametersParserImpl(absl::string_view object_identifier,const std::function<util::StatusOr<ParametersT> (SerializationT)> & function)72   explicit ParametersParserImpl(
73       absl::string_view object_identifier,
74       const std::function<util::StatusOr<ParametersT>(SerializationT)>&
75           function)
76       : object_identifier_(object_identifier), function_(function) {}
77 
ParseParameters(const Serialization & serialization)78   util::StatusOr<std::unique_ptr<Parameters>> ParseParameters(
79       const Serialization& serialization) const override {
80     if (serialization.ObjectIdentifier() != object_identifier_) {
81       return util::Status(
82           absl::StatusCode::kInvalidArgument,
83           "Invalid object identifier for this parameters parser.");
84     }
85     const SerializationT* st =
86         dynamic_cast<const SerializationT*>(&serialization);
87     if (st == nullptr) {
88       return util::Status(
89           absl::StatusCode::kInvalidArgument,
90           "Invalid serialization type for this parameters parser.");
91     }
92     util::StatusOr<ParametersT> parameters = function_(*st);
93     if (!parameters.ok()) return parameters.status();
94     return {absl::make_unique<ParametersT>(std::move(*parameters))};
95   }
96 
ObjectIdentifier()97   absl::string_view ObjectIdentifier() const override {
98     return object_identifier_;
99   }
100 
Index()101   ParserIndex Index() const override {
102     return ParserIndex::Create<SerializationT>(object_identifier_);
103   }
104 
105  private:
106   std::string object_identifier_;
107   std::function<util::StatusOr<ParametersT>(SerializationT)> function_;
108 };
109 
110 }  // namespace internal
111 }  // namespace tink
112 }  // namespace crypto
113 
114 #endif  // TINK_INTERNAL_PARAMETERS_PARSER_H_
115