Repository: envoyproxy/envoy
File: source/extensions/filters/http/proto_api_scrubber/filter_config.cc (C++)

Code before:

    for (const auto& service : file.service()) {
      for (const auto& method : service.method()) {
        // Construct the Method Key (e.g., /package.Service/Method).
        std::string method_key =
            absl::StrCat("/", package_prefix, service.name(), "/", method.name());

        // Resolve Request Type.
        std::string input_type_name = method.input_type();
        if (absl::StartsWith(input_type_name, ".")) {
          input_type_name = input_type_name.substr(1);
        } else if (!package_prefix.empty()) {
          input_type_name = absl::StrCat(package_prefix, input_type_name);
        }

        std::string request_type_url =
            absl::StrCat(Envoy::Grpc::Common::typeUrlPrefix(), "/", input_type_name);

        if (const auto* req_type = (*type_finder_)(request_type_url)) {
          request_type_cache_[method_key] = req_type;
        } else {
          ENVOY_LOG(error, "Failed to resolve Request Type for {}. URL: {}", method_key,
                    request_type_url);
        }

        // Resolve Response Type.
        std::string output_type_name = method.output_type();
        if (absl::StartsWith(output_type_name, ".")) {
          output_type_name = output_type_name.substr(1);
        } else if (!package_prefix.empty()) {
          output_type_name = absl::StrCat(package_prefix, output_type_name);
        }

        std::string response_type_url =
            absl::StrCat(Envoy::Grpc::Common::typeUrlPrefix(), "/", output_type_name);

        if (const auto* resp_type = (*type_finder_)(response_type_url)) {
          response_type_cache_[method_key] = resp_type;
        } else {
          ENVOY_LOG(error, "Failed to resolve Response Type for {}. URL: {}", method_key,
                    response_type_url);
        }
      }
    }
  }
}

absl::StatusOr<const Protobuf::Type*>
ProtoApiScrubberFilterConfig::getRequestType(const std::string& method_name) const {
  auto it = request_type_cache_.find(method_name);
  if (it != request_type_cache_.end()) {

Review comment (performance):
seems like mostly duplicated code for request and response. Will it be possible to create a function that receives the type_name, and ref to type_cache_ and populates it?

Code after:
MatchTreeHttpMatchingDataSharedPtr
ProtoApiScrubberFilterConfig::getMessageMatcher(const std::string& message_name) const {
  if (auto it = message_level_restrictions_.find(message_name);
      it != message_level_restrictions_.end()) {
    return it->second;
  }
  return nullptr;
}

void ProtoApiScrubberFilterConfig::initializeTypeUtils() {
  type_helper_ =
      std::make_unique<const TypeHelper>(Envoy::Protobuf::util::NewTypeResolverForDescriptorPool(
          Envoy::Grpc::Common::typeUrlPrefix(), descriptor_pool_.get()));

  type_finder_ = std::make_unique<const TypeFinder>(
      [this](absl::string_view type_url) -> const ::Envoy::Protobuf::Type* {
        return type_helper_->Info()->GetTypeByTypeUrl(type_url);
      });
}

void ProtoApiScrubberFilterConfig::resolveAndCacheType(
    const std::string& raw_type_name, const std::string& package_prefix,
    const std::string& method_key,
    absl::flat_hash_map<std::string, const Envoy::Protobuf::Type*>& cache,
    absl::string_view type_category) {
  std::string type_name = raw_type_name;

  // Handle fully qualified names starting with "." or append package prefix
  if (absl::StartsWith(type_name, ".")) {
    type_name = type_name.substr(1);
  } else if (!package_prefix.empty()) {
    type_name = absl::StrCat(package_prefix, type_name);
  }

  std::string type_url = absl::StrCat(Envoy::Grpc::Common::typeUrlPrefix(), "/", type_name);

  if (const auto* type_ptr = (*type_finder_)(type_url)) {
    cache[method_key] = type_ptr;
  } else {
    ENVOY_LOG(error, "Failed to resolve {} Type for {}. URL: {}", type_category, method_key,
              type_url);
  }
}

void ProtoApiScrubberFilterConfig::precomputeTypeCache(
    const Envoy::Protobuf::FileDescriptorSet& descriptor_set) {
  for (const auto& file : descriptor_set.file()) {
    std::string package_prefix;
    if (!file.package().empty()) {
      package_prefix = absl::StrCat(file.package(), ".");
    }