1 /*
2  * Copyright (c) Facebook, Inc. and its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <thrift/conformance/cpp2/Any.h>
18 
19 #include <fmt/core.h>
20 #include <folly/lang/Exception.h>
21 #include <thrift/lib/cpp2/type/UniversalName.h>
22 
23 namespace apache::thrift::conformance {
24 using type::validateUniversalName;
25 
getProtocol(const Any & any)26 Protocol getProtocol(const Any& any) noexcept {
27   if (!any.protocol_ref()) {
28     return getStandardProtocol<StandardProtocol::Compact>();
29   }
30   if (*any.protocol_ref() != StandardProtocol::Custom) {
31     return Protocol(*any.get_protocol());
32   }
33   if (any.customProtocol_ref()) {
34     return Protocol(any.customProtocol_ref().value_unchecked());
35   }
36   return {};
37 }
38 
hasProtocol(const Any & any,const Protocol & protocol)39 bool hasProtocol(const Any& any, const Protocol& protocol) noexcept {
40   if (any.get_protocol() == nullptr) {
41     return protocol.standard() == StandardProtocol::Compact;
42   }
43   if (*any.get_protocol() != StandardProtocol::Custom) {
44     return *any.get_protocol() == protocol.standard();
45   }
46   if (any.customProtocol_ref() &&
47       !any.customProtocol_ref().value_unchecked().empty()) {
48     return any.customProtocol_ref().value_unchecked() == protocol.custom();
49   }
50   // `any` has no protocol.
51   return protocol.isNone();
52 }
53 
setProtocol(const Protocol & protocol,Any & any)54 void setProtocol(const Protocol& protocol, Any& any) noexcept {
55   switch (protocol.standard()) {
56     case StandardProtocol::Compact:
57       any.protocol_ref().reset();
58       any.customProtocol_ref().reset();
59       break;
60     case StandardProtocol::Custom:
61       any.set_protocol(StandardProtocol::Custom);
62       any.set_customProtocol(protocol.custom());
63       break;
64     default:
65       any.set_protocol(protocol.standard());
66       any.customProtocol_ref().reset();
67       break;
68   }
69 }
70 
validateAny(const Any & any)71 void validateAny(const Any& any) {
72   if (any.type_ref().has_value() && !any.type_ref().value_unchecked().empty()) {
73     validateUniversalName(any.type_ref().value_unchecked());
74   }
75   if (any.customProtocol_ref().has_value() &&
76       !any.customProtocol_ref().value_unchecked().empty()) {
77     validateUniversalName(any.customProtocol_ref().value_unchecked());
78   }
79 }
80 
81 } // namespace apache::thrift::conformance
82