File indexing completed on 2025-02-28 10:10:19
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef GOOGLE_PROTOBUF_JSON_INTERNAL_PARSER_TRAITS_H__
0009 #define GOOGLE_PROTOBUF_JSON_INTERNAL_PARSER_TRAITS_H__
0010
0011 #include <cfloat>
0012 #include <cmath>
0013 #include <cstdint>
0014 #include <limits>
0015 #include <memory>
0016 #include <string>
0017 #include <utility>
0018
0019 #include "google/protobuf/type.pb.h"
0020 #include "absl/base/attributes.h"
0021 #include "absl/base/casts.h"
0022 #include "absl/container/flat_hash_map.h"
0023 #include "absl/container/flat_hash_set.h"
0024 #include "absl/status/status.h"
0025 #include "absl/strings/str_format.h"
0026 #include "absl/strings/string_view.h"
0027 #include "google/protobuf/io/coded_stream.h"
0028 #include "google/protobuf/io/zero_copy_stream.h"
0029 #include "google/protobuf/io/zero_copy_stream_impl_lite.h"
0030 #include "google/protobuf/json/internal/descriptor_traits.h"
0031 #include "google/protobuf/wire_format_lite.h"
0032 #include "google/protobuf/stubs/status_macros.h"
0033
0034
0035 #include "google/protobuf/port_def.inc"
0036
0037 namespace google {
0038 namespace protobuf {
0039 namespace json_internal {
0040 using ::google::protobuf::internal::WireFormatLite;
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 template <typename Traits>
0051 using Msg = typename Traits::Msg;
0052
0053 struct ParseProto2Descriptor : Proto2Descriptor {
0054
0055 class Msg {
0056 public:
0057 explicit Msg(Message* msg) : msg_(msg) {}
0058
0059 private:
0060 friend ParseProto2Descriptor;
0061 Message* msg_;
0062
0063
0064 absl::flat_hash_set<int> parsed_oneofs_indices_;
0065 absl::flat_hash_set<int> parsed_fields_;
0066 };
0067
0068 static bool HasParsed(Field f, const Msg& msg,
0069 bool allow_repeated_non_oneof) {
0070 if (f->real_containing_oneof()) {
0071 return msg.parsed_oneofs_indices_.contains(
0072 f->real_containing_oneof()->index());
0073 }
0074 if (allow_repeated_non_oneof) {
0075 return false;
0076 }
0077 return msg.parsed_fields_.contains(f->number());
0078 }
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088 static void RecordAsSeen(Field f, Msg& msg) {
0089 bool inserted = msg.parsed_fields_.insert(f->number()).second;
0090 if (inserted) {
0091 msg.msg_->GetReflection()->ClearField(msg.msg_, f);
0092 }
0093
0094 if (f->real_containing_oneof() != nullptr) {
0095 msg.parsed_oneofs_indices_.insert(f->real_containing_oneof()->index());
0096 }
0097 }
0098
0099
0100
0101
0102 template <typename F>
0103 static absl::Status NewMsg(Field f, Msg& msg, F body) {
0104 RecordAsSeen(f, msg);
0105
0106 Message* new_msg;
0107 if (f->is_repeated()) {
0108 new_msg = msg.msg_->GetReflection()->AddMessage(msg.msg_, f);
0109 } else {
0110 new_msg = msg.msg_->GetReflection()->MutableMessage(msg.msg_, f);
0111 }
0112 Msg wrapper(new_msg);
0113 return body(*f->message_type(), wrapper);
0114 }
0115
0116
0117
0118
0119 template <typename F>
0120 static absl::Status NewDynamic(Field f, const std::string& type_url, Msg& msg,
0121 F body) {
0122 RecordAsSeen(f, msg);
0123 return WithDynamicType(
0124 *f->containing_type(), type_url, [&](const Desc& desc) -> absl::Status {
0125 DynamicMessageFactory factory;
0126 std::unique_ptr<Message> dynamic(factory.GetPrototype(&desc)->New());
0127 Msg wrapper(dynamic.get());
0128 RETURN_IF_ERROR(body(desc, wrapper));
0129
0130 if (f->is_repeated()) {
0131 msg.msg_->GetReflection()->AddString(
0132 msg.msg_, f, dynamic->SerializePartialAsString());
0133 } else {
0134 msg.msg_->GetReflection()->SetString(
0135 msg.msg_, f, dynamic->SerializePartialAsString());
0136 }
0137 return absl::OkStatus();
0138 });
0139 }
0140
0141 static void SetFloat(Field f, Msg& msg, float x) {
0142 RecordAsSeen(f, msg);
0143 if (f->is_repeated()) {
0144 msg.msg_->GetReflection()->AddFloat(msg.msg_, f, x);
0145 } else {
0146 msg.msg_->GetReflection()->SetFloat(msg.msg_, f, x);
0147 }
0148 }
0149
0150 static void SetDouble(Field f, Msg& msg, double x) {
0151 if (f->is_repeated()) {
0152 msg.msg_->GetReflection()->AddDouble(msg.msg_, f, x);
0153 } else {
0154 msg.msg_->GetReflection()->SetDouble(msg.msg_, f, x);
0155 }
0156 }
0157
0158 static void SetInt64(Field f, Msg& msg, int64_t x) {
0159 RecordAsSeen(f, msg);
0160 if (f->is_repeated()) {
0161 msg.msg_->GetReflection()->AddInt64(msg.msg_, f, x);
0162 } else {
0163 msg.msg_->GetReflection()->SetInt64(msg.msg_, f, x);
0164 }
0165 }
0166
0167 static void SetUInt64(Field f, Msg& msg, uint64_t x) {
0168 RecordAsSeen(f, msg);
0169 if (f->is_repeated()) {
0170 msg.msg_->GetReflection()->AddUInt64(msg.msg_, f, x);
0171 } else {
0172 msg.msg_->GetReflection()->SetUInt64(msg.msg_, f, x);
0173 }
0174 }
0175
0176 static void SetInt32(Field f, Msg& msg, int32_t x) {
0177 RecordAsSeen(f, msg);
0178 if (f->is_repeated()) {
0179 msg.msg_->GetReflection()->AddInt32(msg.msg_, f, x);
0180 } else {
0181 msg.msg_->GetReflection()->SetInt32(msg.msg_, f, x);
0182 }
0183 }
0184
0185 static void SetUInt32(Field f, Msg& msg, uint32_t x) {
0186 RecordAsSeen(f, msg);
0187 if (f->is_repeated()) {
0188 msg.msg_->GetReflection()->AddUInt32(msg.msg_, f, x);
0189 } else {
0190 msg.msg_->GetReflection()->SetUInt32(msg.msg_, f, x);
0191 }
0192 }
0193
0194 static void SetBool(Field f, Msg& msg, bool x) {
0195 RecordAsSeen(f, msg);
0196 if (f->is_repeated()) {
0197 msg.msg_->GetReflection()->AddBool(msg.msg_, f, x);
0198 } else {
0199 msg.msg_->GetReflection()->SetBool(msg.msg_, f, x);
0200 }
0201 }
0202
0203 static void SetString(Field f, Msg& msg, absl::string_view x) {
0204 RecordAsSeen(f, msg);
0205 if (f->is_repeated()) {
0206 msg.msg_->GetReflection()->AddString(msg.msg_, f, std::string(x));
0207 } else {
0208 msg.msg_->GetReflection()->SetString(msg.msg_, f, std::string(x));
0209 }
0210 }
0211
0212 static void SetEnum(Field f, Msg& msg, int32_t x) {
0213 RecordAsSeen(f, msg);
0214 if (f->is_repeated()) {
0215 msg.msg_->GetReflection()->AddEnumValue(msg.msg_, f, x);
0216 } else {
0217 msg.msg_->GetReflection()->SetEnumValue(msg.msg_, f, x);
0218 }
0219 }
0220 };
0221
0222
0223
0224
0225
0226
0227
0228 struct ParseProto3Type : Proto3Type {
0229 class Msg {
0230 public:
0231 explicit Msg(io::ZeroCopyOutputStream* stream) : stream_(stream) {}
0232
0233 private:
0234 friend ParseProto3Type;
0235 io::CodedOutputStream stream_;
0236 absl::flat_hash_set<int32_t> parsed_oneofs_indices_;
0237 absl::flat_hash_set<int32_t> parsed_fields_;
0238 };
0239
0240 static bool HasParsed(Field f, const Msg& msg,
0241 bool allow_repeated_non_oneof) {
0242 if (f->proto().oneof_index() != 0) {
0243 return msg.parsed_oneofs_indices_.contains(f->proto().oneof_index());
0244 }
0245 if (allow_repeated_non_oneof) {
0246 return false;
0247 }
0248 return msg.parsed_fields_.contains(f->proto().number());
0249 }
0250
0251
0252
0253 static void RecordAsSeen(Field f, Msg& msg) {
0254 msg.parsed_fields_.insert(f->proto().number());
0255 if (f->proto().oneof_index() != 0) {
0256 msg.parsed_oneofs_indices_.insert(f->proto().oneof_index());
0257 }
0258 }
0259
0260 template <typename F>
0261 static absl::Status NewMsg(Field f, Msg& msg, F body) {
0262 return NewDynamic(f, f->proto().type_url(), msg, body);
0263 }
0264
0265 template <typename F>
0266 static absl::Status NewDynamic(Field f, const std::string& type_url, Msg& msg,
0267 F body) {
0268 RecordAsSeen(f, msg);
0269 return WithDynamicType(
0270 f->parent(), type_url, [&](const Desc& desc) -> absl::Status {
0271 if (f->proto().kind() == google::protobuf::Field::TYPE_GROUP) {
0272 msg.stream_.WriteTag(f->proto().number() << 3 |
0273 WireFormatLite::WIRETYPE_START_GROUP);
0274 RETURN_IF_ERROR(body(desc, msg));
0275 msg.stream_.WriteTag(f->proto().number() << 3 |
0276 WireFormatLite::WIRETYPE_END_GROUP);
0277 return absl::OkStatus();
0278 }
0279
0280 std::string out;
0281 io::StringOutputStream stream(&out);
0282 Msg new_msg(&stream);
0283 RETURN_IF_ERROR(body(desc, new_msg));
0284
0285 new_msg.stream_.Trim();
0286 absl::string_view written(
0287 out.data(), static_cast<size_t>(new_msg.stream_.ByteCount()));
0288 SetString(f, msg, written);
0289 return absl::OkStatus();
0290 });
0291 }
0292
0293 static void SetFloat(Field f, Msg& msg, float x) {
0294 RecordAsSeen(f, msg);
0295 msg.stream_.WriteTag(f->proto().number() << 3 |
0296 WireFormatLite::WIRETYPE_FIXED32);
0297 msg.stream_.WriteLittleEndian32(absl::bit_cast<uint32_t>(x));
0298 }
0299
0300 static void SetDouble(Field f, Msg& msg, double x) {
0301 RecordAsSeen(f, msg);
0302 msg.stream_.WriteTag(f->proto().number() << 3 |
0303 WireFormatLite::WIRETYPE_FIXED64);
0304 msg.stream_.WriteLittleEndian64(absl::bit_cast<uint64_t>(x));
0305 }
0306
0307 static void SetInt64(Field f, Msg& msg, int64_t x) {
0308 SetInt<int64_t, google::protobuf::Field::TYPE_INT64,
0309 google::protobuf::Field::TYPE_SFIXED64,
0310 google::protobuf::Field::TYPE_SINT64>(f, msg, x);
0311 }
0312
0313 static void SetUInt64(Field f, Msg& msg, uint64_t x) {
0314 SetInt<uint64_t, google::protobuf::Field::TYPE_UINT64,
0315 google::protobuf::Field::TYPE_FIXED64,
0316 google::protobuf::Field::TYPE_UNKNOWN>(f, msg, x);
0317 }
0318
0319 static void SetInt32(Field f, Msg& msg, int32_t x) {
0320 SetInt<int32_t, google::protobuf::Field::TYPE_INT32,
0321 google::protobuf::Field::TYPE_SFIXED32,
0322 google::protobuf::Field::TYPE_SINT32>(f, msg, x);
0323 }
0324
0325 static void SetUInt32(Field f, Msg& msg, uint32_t x) {
0326 SetInt<uint32_t, google::protobuf::Field::TYPE_UINT32,
0327 google::protobuf::Field::TYPE_FIXED32,
0328 google::protobuf::Field::TYPE_UNKNOWN>(f, msg, x);
0329 }
0330
0331 static void SetBool(Field f, Msg& msg, bool x) {
0332 RecordAsSeen(f, msg);
0333 msg.stream_.WriteTag(f->proto().number() << 3);
0334 char b = x ? 0x01 : 0x00;
0335 msg.stream_.WriteRaw(&b, 1);
0336 }
0337
0338 static void SetString(Field f, Msg& msg, absl::string_view x) {
0339 RecordAsSeen(f, msg);
0340 msg.stream_.WriteTag(f->proto().number() << 3 |
0341 WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
0342 msg.stream_.WriteVarint64(static_cast<uint64_t>(x.size()));
0343 msg.stream_.WriteRaw(x.data(), x.size());
0344 }
0345
0346 static void SetEnum(Field f, Msg& msg, int32_t x) {
0347 RecordAsSeen(f, msg);
0348 msg.stream_.WriteTag(f->proto().number() << 3);
0349
0350 msg.stream_.WriteVarint32(x);
0351 }
0352
0353 private:
0354 using Kind = google::protobuf::Field::Kind;
0355
0356
0357
0358 template <typename Int, Kind varint, Kind fixed, Kind zigzag>
0359 static void SetInt(Field f, Msg& msg, Int x) {
0360 RecordAsSeen(f, msg);
0361 switch (f->proto().kind()) {
0362 case zigzag:
0363
0364
0365
0366 x = static_cast<Int>(
0367 internal::WireFormatLite::ZigZagEncode64(static_cast<int64_t>(x)));
0368 ABSL_FALLTHROUGH_INTENDED;
0369 case varint:
0370 msg.stream_.WriteTag(f->proto().number() << 3 |
0371 WireFormatLite::WIRETYPE_VARINT);
0372 if (sizeof(Int) == 4) {
0373 msg.stream_.WriteVarint32(static_cast<uint32_t>(x));
0374 } else {
0375 msg.stream_.WriteVarint64(static_cast<uint64_t>(x));
0376 }
0377 break;
0378 case fixed: {
0379 if (sizeof(Int) == 4) {
0380 msg.stream_.WriteTag(f->proto().number() << 3 |
0381 WireFormatLite::WIRETYPE_FIXED32);
0382 msg.stream_.WriteLittleEndian32(static_cast<uint32_t>(x));
0383 } else {
0384 msg.stream_.WriteTag(f->proto().number() << 3 |
0385 WireFormatLite::WIRETYPE_FIXED64);
0386 msg.stream_.WriteLittleEndian64(static_cast<uint64_t>(x));
0387 }
0388 break;
0389 }
0390 default: {
0391 }
0392 }
0393 }
0394 };
0395 }
0396 }
0397 }
0398
0399 #include "google/protobuf/port_undef.inc"
0400 #endif