LCOV - code coverage report
Current view: top level - source/common/protobuf - visitor.cc (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 29 52 55.8 %
Date: 2024-01-05 06:35:25 Functions: 2 2 100.0 %

          Line data    Source code
       1             : #include "source/common/protobuf/visitor.h"
       2             : 
       3             : #include <vector>
       4             : 
       5             : #include "source/common/protobuf/utility.h"
       6             : #include "source/common/protobuf/visitor_helper.h"
       7             : 
       8             : #include "udpa/type/v1/typed_struct.pb.h"
       9             : #include "xds/type/v3/typed_struct.pb.h"
      10             : 
      11             : namespace Envoy {
      12             : namespace ProtobufMessage {
      13             : namespace {
      14             : 
      15             : void traverseMessageWorker(ConstProtoVisitor& visitor, const Protobuf::Message& message,
      16             :                            std::vector<const Protobuf::Message*>& parents,
      17      170664 :                            bool was_any_or_top_level, bool recurse_into_any) {
      18      170664 :   visitor.onMessage(message, parents, was_any_or_top_level);
      19             : 
      20             :   // If told to recurse into Any messages, do that here and skip the rest of the function.
      21      170664 :   if (recurse_into_any) {
      22           0 :     std::unique_ptr<Protobuf::Message> inner_message;
      23           0 :     absl::string_view target_type_url;
      24             : 
      25           0 :     if (message.GetTypeName() == "google.protobuf.Any") {
      26           0 :       auto* any_message = Protobuf::DynamicCastToGenerated<ProtobufWkt::Any>(&message);
      27           0 :       inner_message = Helper::typeUrlToMessage(any_message->type_url());
      28           0 :       target_type_url = any_message->type_url();
      29             :       // inner_message must be valid as parsing would have already failed to load if there was an
      30             :       // invalid type_url.
      31           0 :       MessageUtil::unpackTo(*any_message, *inner_message);
      32           0 :     } else if (message.GetTypeName() == "xds.type.v3.TypedStruct") {
      33           0 :       std::tie(inner_message, target_type_url) =
      34           0 :           Helper::convertTypedStruct<xds::type::v3::TypedStruct>(message);
      35           0 :     } else if (message.GetTypeName() == "udpa.type.v1.TypedStruct") {
      36           0 :       std::tie(inner_message, target_type_url) =
      37           0 :           Helper::convertTypedStruct<udpa::type::v1::TypedStruct>(message);
      38           0 :     }
      39             : 
      40           0 :     if (inner_message != nullptr) {
      41             :       // Push the Any message as a wrapper.
      42           0 :       Helper::ScopedMessageParents scoped_parents(parents, message);
      43           0 :       traverseMessageWorker(visitor, *inner_message, parents, true, recurse_into_any);
      44           0 :       return;
      45           0 :     } else if (!target_type_url.empty()) {
      46           0 :       throwEnvoyExceptionOrPanic(
      47           0 :           fmt::format("Invalid type_url '{}' during traversal", target_type_url));
      48           0 :     }
      49           0 :   }
      50      170664 :   Protobuf::ReflectableMessage reflectable_message = createReflectableMessage(message);
      51      170664 :   const Protobuf::Descriptor* descriptor = reflectable_message->GetDescriptor();
      52      170664 :   const Protobuf::Reflection* reflection = reflectable_message->GetReflection();
      53     1498268 :   for (int i = 0; i < descriptor->field_count(); ++i) {
      54     1327604 :     const Protobuf::FieldDescriptor* field = descriptor->field(i);
      55     1327604 :     visitor.onField(message, *field);
      56             : 
      57             :     // If this is a message, recurse in to the sub-message.
      58     1327604 :     if (field->cpp_type() == Protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
      59      847850 :       Helper::ScopedMessageParents scoped_parents(parents, message);
      60             : 
      61      847850 :       if (field->is_repeated()) {
      62      176541 :         const int size = reflection->FieldSize(*reflectable_message, field);
      63      243302 :         for (int j = 0; j < size; ++j) {
      64       66761 :           traverseMessageWorker(visitor,
      65       66761 :                                 reflection->GetRepeatedMessage(*reflectable_message, field, j),
      66       66761 :                                 parents, false, recurse_into_any);
      67       66761 :         }
      68      671309 :       } else if (reflection->HasField(*reflectable_message, field)) {
      69       93080 :         traverseMessageWorker(visitor, reflection->GetMessage(*reflectable_message, field), parents,
      70       93080 :                               false, recurse_into_any);
      71       93080 :       }
      72      847850 :     }
      73     1327604 :   }
      74      170664 : }
      75             : 
      76             : } // namespace
      77             : 
      78             : void traverseMessage(ConstProtoVisitor& visitor, const Protobuf::Message& message,
      79       10823 :                      bool recurse_into_any) {
      80       10823 :   std::vector<const Protobuf::Message*> parents;
      81       10823 :   traverseMessageWorker(visitor, message, parents, true, recurse_into_any);
      82       10823 : }
      83             : 
      84             : } // namespace ProtobufMessage
      85             : } // namespace Envoy

Generated by: LCOV version 1.15