Coverage Report

Created: 2026-05-27 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/proc/self/cwd/eval/public/message_wrapper.h
Line
Count
Source
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
//     https://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
#ifndef THIRD_PARTY_CEL_CPP_EVAL_PUBLIC_MESSAGE_WRAPPER_H_
16
#define THIRD_PARTY_CEL_CPP_EVAL_PUBLIC_MESSAGE_WRAPPER_H_
17
18
#include <cstdint>
19
20
#include "absl/base/attributes.h"
21
#include "absl/base/macros.h"
22
#include "absl/numeric/bits.h"
23
#include "base/internal/message_wrapper.h"
24
#include "google/protobuf/message.h"
25
#include "google/protobuf/message_lite.h"
26
27
namespace cel::interop_internal {
28
struct MessageWrapperAccess;
29
}  // namespace cel::interop_internal
30
31
namespace google::api::expr::runtime {
32
33
// Forward declare to resolve cycle.
34
class LegacyTypeInfoApis;
35
36
// Wrapper type for protobuf messages. This is used to limit internal usages of
37
// proto APIs and to support working with the proto lite runtime.
38
//
39
// Provides operations for checking if down-casting to Message is safe.
40
class ABSL_DEPRECATED("Use google::protobuf::Message directly") MessageWrapper {
41
 public:
42
  // Simple builder class.
43
  //
44
  // Wraps a tagged mutable message lite ptr.
45
  class ABSL_DEPRECATED("Use google::protobuf::Message directly") Builder {
46
   public:
47
    explicit Builder(google::protobuf::MessageLite* message)
48
0
        : message_ptr_(reinterpret_cast<uintptr_t>(message)) {
49
0
      ABSL_ASSERT(absl::countr_zero(reinterpret_cast<uintptr_t>(message)) >=
50
0
                  kTagSize);
51
0
    }
52
    explicit Builder(google::protobuf::Message* message)
53
1.65k
        : message_ptr_(reinterpret_cast<uintptr_t>(message) | kMessageTag) {
54
1.65k
      ABSL_ASSERT(absl::countr_zero(reinterpret_cast<uintptr_t>(message)) >=
55
1.65k
                  kTagSize);
56
1.65k
    }
57
58
3.30k
    google::protobuf::MessageLite* message_ptr() const {
59
3.30k
      return reinterpret_cast<google::protobuf::MessageLite*>(message_ptr_ & kPtrMask);
60
3.30k
    }
61
62
1.65k
    bool HasFullProto() const {
63
1.65k
      return (message_ptr_ & kTagMask) == kMessageTag;
64
1.65k
    }
65
66
0
    MessageWrapper Build(const LegacyTypeInfoApis* type_info) {
67
0
      return MessageWrapper(message_ptr_, type_info);
68
0
    }
69
70
   private:
71
    friend class MessageWrapper;
72
73
0
    explicit Builder(uintptr_t message_ptr) : message_ptr_(message_ptr) {}
74
75
    uintptr_t message_ptr_;
76
  };
77
78
  static_assert(alignof(google::protobuf::MessageLite) >= 2,
79
                "Assume that valid MessageLite ptrs have a free low-order bit");
80
338
  MessageWrapper() : message_ptr_(0), legacy_type_info_(nullptr) {}
81
82
  MessageWrapper(const google::protobuf::MessageLite* message,
83
                 const LegacyTypeInfoApis* legacy_type_info)
84
      : message_ptr_(reinterpret_cast<uintptr_t>(message)),
85
0
        legacy_type_info_(legacy_type_info) {
86
0
    ABSL_ASSERT(absl::countr_zero(reinterpret_cast<uintptr_t>(message)) >=
87
0
                kTagSize);
88
0
  }
89
90
  MessageWrapper(const google::protobuf::Message* message,
91
                 const LegacyTypeInfoApis* legacy_type_info)
92
574
      : message_ptr_(reinterpret_cast<uintptr_t>(message) | kMessageTag),
93
574
        legacy_type_info_(legacy_type_info) {
94
574
    ABSL_ASSERT(absl::countr_zero(reinterpret_cast<uintptr_t>(message)) >=
95
574
                kTagSize);
96
574
  }
97
98
  // If true, the message is using the full proto runtime and downcasting to
99
  // message should be safe.
100
284
  bool HasFullProto() const { return (message_ptr_ & kTagMask) == kMessageTag; }
101
102
  // Returns the underlying message.
103
  //
104
  // Clients must check HasFullProto before downcasting to Message.
105
1.14k
  const google::protobuf::MessageLite* message_ptr() const {
106
1.14k
    return reinterpret_cast<const google::protobuf::MessageLite*>(message_ptr_ &
107
1.14k
                                                        kPtrMask);
108
1.14k
  }
109
110
  // Type information associated with this message.
111
863
  const LegacyTypeInfoApis* legacy_type_info() const {
112
863
    return legacy_type_info_;
113
863
  }
114
115
 private:
116
  friend struct ::cel::interop_internal::MessageWrapperAccess;
117
118
  MessageWrapper(uintptr_t message_ptr,
119
                 const LegacyTypeInfoApis* legacy_type_info)
120
0
      : message_ptr_(message_ptr), legacy_type_info_(legacy_type_info) {}
121
122
0
  Builder ToBuilder() { return Builder(message_ptr_); }
123
124
  static constexpr int kTagSize = ::cel::base_internal::kMessageWrapperTagSize;
125
  static constexpr uintptr_t kTagMask =
126
      ::cel::base_internal::kMessageWrapperTagMask;
127
  static constexpr uintptr_t kPtrMask =
128
      ::cel::base_internal::kMessageWrapperPtrMask;
129
  static constexpr uintptr_t kMessageTag =
130
      ::cel::base_internal::kMessageWrapperTagMessageValue;
131
  uintptr_t message_ptr_;
132
  const LegacyTypeInfoApis* legacy_type_info_;
133
};
134
135
static_assert(sizeof(MessageWrapper) <= 2 * sizeof(uintptr_t),
136
              "MessageWrapper must not increase CelValue size.");
137
138
}  // namespace google::api::expr::runtime
139
#endif  // THIRD_PARTY_CEL_CPP_EVAL_PUBLIC_MESSAGE_WRAPPER_H_