xref: /aosp_15_r20/external/libtextclassifier/native/utils/grammar/semantics/value.h (revision 993b0882672172b81d12fad7a7ac0c3e5c824a12)
1*993b0882SAndroid Build Coastguard Worker /*
2*993b0882SAndroid Build Coastguard Worker  * Copyright (C) 2018 The Android Open Source Project
3*993b0882SAndroid Build Coastguard Worker  *
4*993b0882SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*993b0882SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*993b0882SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*993b0882SAndroid Build Coastguard Worker  *
8*993b0882SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*993b0882SAndroid Build Coastguard Worker  *
10*993b0882SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*993b0882SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*993b0882SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*993b0882SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*993b0882SAndroid Build Coastguard Worker  * limitations under the License.
15*993b0882SAndroid Build Coastguard Worker  */
16*993b0882SAndroid Build Coastguard Worker 
17*993b0882SAndroid Build Coastguard Worker #ifndef LIBTEXTCLASSIFIER_UTILS_GRAMMAR_SEMANTICS_VALUE_H_
18*993b0882SAndroid Build Coastguard Worker #define LIBTEXTCLASSIFIER_UTILS_GRAMMAR_SEMANTICS_VALUE_H_
19*993b0882SAndroid Build Coastguard Worker 
20*993b0882SAndroid Build Coastguard Worker #include "utils/base/arena.h"
21*993b0882SAndroid Build Coastguard Worker #include "utils/base/logging.h"
22*993b0882SAndroid Build Coastguard Worker #include "utils/flatbuffers/mutable.h"
23*993b0882SAndroid Build Coastguard Worker #include "utils/flatbuffers/reflection.h"
24*993b0882SAndroid Build Coastguard Worker #include "utils/strings/stringpiece.h"
25*993b0882SAndroid Build Coastguard Worker #include "utils/utf8/unicodetext.h"
26*993b0882SAndroid Build Coastguard Worker #include "flatbuffers/base.h"
27*993b0882SAndroid Build Coastguard Worker #include "flatbuffers/reflection.h"
28*993b0882SAndroid Build Coastguard Worker 
29*993b0882SAndroid Build Coastguard Worker namespace libtextclassifier3::grammar {
30*993b0882SAndroid Build Coastguard Worker 
31*993b0882SAndroid Build Coastguard Worker // A semantic value as a typed, arena-allocated flatbuffer.
32*993b0882SAndroid Build Coastguard Worker // This denotes the possible results of the evaluation of a semantic expression.
33*993b0882SAndroid Build Coastguard Worker class SemanticValue {
34*993b0882SAndroid Build Coastguard Worker  public:
35*993b0882SAndroid Build Coastguard Worker   // Creates an arena allocated semantic value.
36*993b0882SAndroid Build Coastguard Worker   template <typename T>
Create(const T value,UnsafeArena * arena)37*993b0882SAndroid Build Coastguard Worker   static const SemanticValue* Create(const T value, UnsafeArena* arena) {
38*993b0882SAndroid Build Coastguard Worker     static_assert(!std::is_pointer<T>() && std::is_scalar<T>());
39*993b0882SAndroid Build Coastguard Worker     if (char* buffer = reinterpret_cast<char*>(
40*993b0882SAndroid Build Coastguard Worker             arena->AllocAligned(sizeof(T), alignof(T)))) {
41*993b0882SAndroid Build Coastguard Worker       flatbuffers::WriteScalar<T>(buffer, value);
42*993b0882SAndroid Build Coastguard Worker       return arena->AllocAndInit<SemanticValue>(
43*993b0882SAndroid Build Coastguard Worker           libtextclassifier3::flatbuffers_base_type<T>::value,
44*993b0882SAndroid Build Coastguard Worker           StringPiece(buffer, sizeof(T)));
45*993b0882SAndroid Build Coastguard Worker     }
46*993b0882SAndroid Build Coastguard Worker     return nullptr;
47*993b0882SAndroid Build Coastguard Worker   }
48*993b0882SAndroid Build Coastguard Worker 
49*993b0882SAndroid Build Coastguard Worker   template <>
Create(const StringPiece value,UnsafeArena * arena)50*993b0882SAndroid Build Coastguard Worker   const SemanticValue* Create(const StringPiece value, UnsafeArena* arena) {
51*993b0882SAndroid Build Coastguard Worker     return arena->AllocAndInit<SemanticValue>(reflection::BaseType::String,
52*993b0882SAndroid Build Coastguard Worker                                               value);
53*993b0882SAndroid Build Coastguard Worker   }
54*993b0882SAndroid Build Coastguard Worker 
55*993b0882SAndroid Build Coastguard Worker   template <>
Create(const UnicodeText value,UnsafeArena * arena)56*993b0882SAndroid Build Coastguard Worker   const SemanticValue* Create(const UnicodeText value, UnsafeArena* arena) {
57*993b0882SAndroid Build Coastguard Worker     return arena->AllocAndInit<SemanticValue>(
58*993b0882SAndroid Build Coastguard Worker         reflection::BaseType::String,
59*993b0882SAndroid Build Coastguard Worker         StringPiece(value.data(), value.size_bytes()));
60*993b0882SAndroid Build Coastguard Worker   }
61*993b0882SAndroid Build Coastguard Worker 
62*993b0882SAndroid Build Coastguard Worker   template <>
Create(const MutableFlatbuffer * value,UnsafeArena * arena)63*993b0882SAndroid Build Coastguard Worker   const SemanticValue* Create(const MutableFlatbuffer* value,
64*993b0882SAndroid Build Coastguard Worker                               UnsafeArena* arena) {
65*993b0882SAndroid Build Coastguard Worker     const std::string buffer = value->Serialize();
66*993b0882SAndroid Build Coastguard Worker     return Create(
67*993b0882SAndroid Build Coastguard Worker         value->type(),
68*993b0882SAndroid Build Coastguard Worker         StringPiece(arena->Memdup(buffer.data(), buffer.size()), buffer.size()),
69*993b0882SAndroid Build Coastguard Worker         arena);
70*993b0882SAndroid Build Coastguard Worker   }
71*993b0882SAndroid Build Coastguard Worker 
Create(const reflection::Object * type,const StringPiece data,UnsafeArena * arena)72*993b0882SAndroid Build Coastguard Worker   static const SemanticValue* Create(const reflection::Object* type,
73*993b0882SAndroid Build Coastguard Worker                                      const StringPiece data,
74*993b0882SAndroid Build Coastguard Worker                                      UnsafeArena* arena) {
75*993b0882SAndroid Build Coastguard Worker     return arena->AllocAndInit<SemanticValue>(type, data);
76*993b0882SAndroid Build Coastguard Worker   }
77*993b0882SAndroid Build Coastguard Worker 
Create(const reflection::BaseType base_type,const StringPiece data,UnsafeArena * arena)78*993b0882SAndroid Build Coastguard Worker   static const SemanticValue* Create(const reflection::BaseType base_type,
79*993b0882SAndroid Build Coastguard Worker                                      const StringPiece data,
80*993b0882SAndroid Build Coastguard Worker                                      UnsafeArena* arena) {
81*993b0882SAndroid Build Coastguard Worker     return arena->AllocAndInit<SemanticValue>(base_type, data);
82*993b0882SAndroid Build Coastguard Worker   }
83*993b0882SAndroid Build Coastguard Worker 
84*993b0882SAndroid Build Coastguard Worker   template <typename T>
Create(const reflection::BaseType base_type,const T value,UnsafeArena * arena)85*993b0882SAndroid Build Coastguard Worker   static const SemanticValue* Create(const reflection::BaseType base_type,
86*993b0882SAndroid Build Coastguard Worker                                      const T value, UnsafeArena* arena) {
87*993b0882SAndroid Build Coastguard Worker     switch (base_type) {
88*993b0882SAndroid Build Coastguard Worker       case reflection::BaseType::Bool:
89*993b0882SAndroid Build Coastguard Worker         return Create(
90*993b0882SAndroid Build Coastguard Worker             static_cast<
91*993b0882SAndroid Build Coastguard Worker                 flatbuffers_cpp_type<reflection::BaseType::Bool>::value>(value),
92*993b0882SAndroid Build Coastguard Worker             arena);
93*993b0882SAndroid Build Coastguard Worker       case reflection::BaseType::Byte:
94*993b0882SAndroid Build Coastguard Worker         return Create(
95*993b0882SAndroid Build Coastguard Worker             static_cast<
96*993b0882SAndroid Build Coastguard Worker                 flatbuffers_cpp_type<reflection::BaseType::Byte>::value>(value),
97*993b0882SAndroid Build Coastguard Worker             arena);
98*993b0882SAndroid Build Coastguard Worker       case reflection::BaseType::UByte:
99*993b0882SAndroid Build Coastguard Worker         return Create(
100*993b0882SAndroid Build Coastguard Worker             static_cast<
101*993b0882SAndroid Build Coastguard Worker                 flatbuffers_cpp_type<reflection::BaseType::UByte>::value>(
102*993b0882SAndroid Build Coastguard Worker                 value),
103*993b0882SAndroid Build Coastguard Worker             arena);
104*993b0882SAndroid Build Coastguard Worker       case reflection::BaseType::Short:
105*993b0882SAndroid Build Coastguard Worker         return Create(
106*993b0882SAndroid Build Coastguard Worker             static_cast<
107*993b0882SAndroid Build Coastguard Worker                 flatbuffers_cpp_type<reflection::BaseType::Short>::value>(
108*993b0882SAndroid Build Coastguard Worker                 value),
109*993b0882SAndroid Build Coastguard Worker             arena);
110*993b0882SAndroid Build Coastguard Worker       case reflection::BaseType::UShort:
111*993b0882SAndroid Build Coastguard Worker         return Create(
112*993b0882SAndroid Build Coastguard Worker             static_cast<
113*993b0882SAndroid Build Coastguard Worker                 flatbuffers_cpp_type<reflection::BaseType::UShort>::value>(
114*993b0882SAndroid Build Coastguard Worker                 value),
115*993b0882SAndroid Build Coastguard Worker             arena);
116*993b0882SAndroid Build Coastguard Worker       case reflection::BaseType::Int:
117*993b0882SAndroid Build Coastguard Worker         return Create(
118*993b0882SAndroid Build Coastguard Worker             static_cast<flatbuffers_cpp_type<reflection::BaseType::Int>::value>(
119*993b0882SAndroid Build Coastguard Worker                 value),
120*993b0882SAndroid Build Coastguard Worker             arena);
121*993b0882SAndroid Build Coastguard Worker       case reflection::BaseType::UInt:
122*993b0882SAndroid Build Coastguard Worker         return Create(
123*993b0882SAndroid Build Coastguard Worker             static_cast<
124*993b0882SAndroid Build Coastguard Worker                 flatbuffers_cpp_type<reflection::BaseType::UInt>::value>(value),
125*993b0882SAndroid Build Coastguard Worker             arena);
126*993b0882SAndroid Build Coastguard Worker       case reflection::BaseType::Long:
127*993b0882SAndroid Build Coastguard Worker         return Create(
128*993b0882SAndroid Build Coastguard Worker             static_cast<
129*993b0882SAndroid Build Coastguard Worker                 flatbuffers_cpp_type<reflection::BaseType::Long>::value>(value),
130*993b0882SAndroid Build Coastguard Worker             arena);
131*993b0882SAndroid Build Coastguard Worker       case reflection::BaseType::ULong:
132*993b0882SAndroid Build Coastguard Worker         return Create(
133*993b0882SAndroid Build Coastguard Worker             static_cast<
134*993b0882SAndroid Build Coastguard Worker                 flatbuffers_cpp_type<reflection::BaseType::ULong>::value>(
135*993b0882SAndroid Build Coastguard Worker                 value),
136*993b0882SAndroid Build Coastguard Worker             arena);
137*993b0882SAndroid Build Coastguard Worker       case reflection::BaseType::Float:
138*993b0882SAndroid Build Coastguard Worker         return Create(
139*993b0882SAndroid Build Coastguard Worker             static_cast<
140*993b0882SAndroid Build Coastguard Worker                 flatbuffers_cpp_type<reflection::BaseType::Float>::value>(
141*993b0882SAndroid Build Coastguard Worker                 value),
142*993b0882SAndroid Build Coastguard Worker             arena);
143*993b0882SAndroid Build Coastguard Worker       case reflection::BaseType::Double:
144*993b0882SAndroid Build Coastguard Worker         return Create(
145*993b0882SAndroid Build Coastguard Worker             static_cast<
146*993b0882SAndroid Build Coastguard Worker                 flatbuffers_cpp_type<reflection::BaseType::Double>::value>(
147*993b0882SAndroid Build Coastguard Worker                 value),
148*993b0882SAndroid Build Coastguard Worker             arena);
149*993b0882SAndroid Build Coastguard Worker       default: {
150*993b0882SAndroid Build Coastguard Worker         TC3_LOG(ERROR) << "Unhandled type: " << base_type;
151*993b0882SAndroid Build Coastguard Worker         return nullptr;
152*993b0882SAndroid Build Coastguard Worker       }
153*993b0882SAndroid Build Coastguard Worker     }
154*993b0882SAndroid Build Coastguard Worker   }
155*993b0882SAndroid Build Coastguard Worker 
SemanticValue(const reflection::BaseType base_type,const StringPiece data)156*993b0882SAndroid Build Coastguard Worker   explicit SemanticValue(const reflection::BaseType base_type,
157*993b0882SAndroid Build Coastguard Worker                          const StringPiece data)
158*993b0882SAndroid Build Coastguard Worker       : base_type_(base_type), type_(nullptr), data_(data) {}
SemanticValue(const reflection::Object * type,const StringPiece data)159*993b0882SAndroid Build Coastguard Worker   explicit SemanticValue(const reflection::Object* type, const StringPiece data)
160*993b0882SAndroid Build Coastguard Worker       : base_type_(reflection::BaseType::Obj), type_(type), data_(data) {}
161*993b0882SAndroid Build Coastguard Worker 
162*993b0882SAndroid Build Coastguard Worker   template <typename T>
Has()163*993b0882SAndroid Build Coastguard Worker   bool Has() const {
164*993b0882SAndroid Build Coastguard Worker     return base_type_ == libtextclassifier3::flatbuffers_base_type<T>::value;
165*993b0882SAndroid Build Coastguard Worker   }
166*993b0882SAndroid Build Coastguard Worker 
167*993b0882SAndroid Build Coastguard Worker   template <>
168*993b0882SAndroid Build Coastguard Worker   bool Has<flatbuffers::Table>() const {
169*993b0882SAndroid Build Coastguard Worker     return base_type_ == reflection::BaseType::Obj;
170*993b0882SAndroid Build Coastguard Worker   }
171*993b0882SAndroid Build Coastguard Worker 
172*993b0882SAndroid Build Coastguard Worker   template <typename T = flatbuffers::Table>
Table()173*993b0882SAndroid Build Coastguard Worker   const T* Table() const {
174*993b0882SAndroid Build Coastguard Worker     TC3_CHECK(Has<flatbuffers::Table>());
175*993b0882SAndroid Build Coastguard Worker     return flatbuffers::GetRoot<T>(
176*993b0882SAndroid Build Coastguard Worker         reinterpret_cast<const unsigned char*>(data_.data()));
177*993b0882SAndroid Build Coastguard Worker   }
178*993b0882SAndroid Build Coastguard Worker 
179*993b0882SAndroid Build Coastguard Worker   template <typename T>
Value()180*993b0882SAndroid Build Coastguard Worker   const T Value() const {
181*993b0882SAndroid Build Coastguard Worker     TC3_CHECK(Has<T>());
182*993b0882SAndroid Build Coastguard Worker     return flatbuffers::ReadScalar<T>(data_.data());
183*993b0882SAndroid Build Coastguard Worker   }
184*993b0882SAndroid Build Coastguard Worker 
185*993b0882SAndroid Build Coastguard Worker   template <>
186*993b0882SAndroid Build Coastguard Worker   const StringPiece Value<StringPiece>() const {
187*993b0882SAndroid Build Coastguard Worker     TC3_CHECK(Has<StringPiece>());
188*993b0882SAndroid Build Coastguard Worker     return data_;
189*993b0882SAndroid Build Coastguard Worker   }
190*993b0882SAndroid Build Coastguard Worker 
191*993b0882SAndroid Build Coastguard Worker   template <>
192*993b0882SAndroid Build Coastguard Worker   const std::string Value<std::string>() const {
193*993b0882SAndroid Build Coastguard Worker     TC3_CHECK(Has<StringPiece>());
194*993b0882SAndroid Build Coastguard Worker     return data_.ToString();
195*993b0882SAndroid Build Coastguard Worker   }
196*993b0882SAndroid Build Coastguard Worker 
197*993b0882SAndroid Build Coastguard Worker   template <>
198*993b0882SAndroid Build Coastguard Worker   const UnicodeText Value<UnicodeText>() const {
199*993b0882SAndroid Build Coastguard Worker     TC3_CHECK(Has<StringPiece>());
200*993b0882SAndroid Build Coastguard Worker     return UTF8ToUnicodeText(data_, /*do_copy=*/false);
201*993b0882SAndroid Build Coastguard Worker   }
202*993b0882SAndroid Build Coastguard Worker 
base_type()203*993b0882SAndroid Build Coastguard Worker   const reflection::BaseType base_type() const { return base_type_; }
type()204*993b0882SAndroid Build Coastguard Worker   const reflection::Object* type() const { return type_; }
205*993b0882SAndroid Build Coastguard Worker 
206*993b0882SAndroid Build Coastguard Worker  private:
207*993b0882SAndroid Build Coastguard Worker   // The base type.
208*993b0882SAndroid Build Coastguard Worker   const reflection::BaseType base_type_;
209*993b0882SAndroid Build Coastguard Worker 
210*993b0882SAndroid Build Coastguard Worker   // The object type of the value.
211*993b0882SAndroid Build Coastguard Worker   const reflection::Object* type_;
212*993b0882SAndroid Build Coastguard Worker 
213*993b0882SAndroid Build Coastguard Worker   StringPiece data_;
214*993b0882SAndroid Build Coastguard Worker };
215*993b0882SAndroid Build Coastguard Worker 
216*993b0882SAndroid Build Coastguard Worker }  // namespace libtextclassifier3::grammar
217*993b0882SAndroid Build Coastguard Worker 
218*993b0882SAndroid Build Coastguard Worker #endif  // LIBTEXTCLASSIFIER_UTILS_GRAMMAR_SEMANTICS_VALUE_H_
219