mirror of
https://github.com/protocolbuffers/protobuf
synced 2026-08-26 02:23:14 -04:00
With this change, we no longer emit any C generated code for the Rust upb implementation. Instead, we output minidescriptors in the Rust generated code, and use these to construct the minitables at run time. Each message's `AssociatedMiniTable::mini_table()` method will lazily build the minitable on first use. We need a place to put the minidescriptor and lazily-built minitable for enums, so I added a new `AssociatedMiniTableEnum` trait for this purpose. This is only necessary for closed enums. There are a couple of things that were somewhat difficult about building the minitables at runtime: - Each map entry is represented as its own implicit message type and needs a minitable. To facilitate this, I updated the generator to output a visibility-controlled struct to represent each map entry. This way we can implement `AssociatedMiniTable` on it and treat it like any other message for the purpose of building minitables. - The naive way of recursively building minitables is vulnerable to deadlock in the case of cycles in the message graph. Such cycles are allowed within a single .proto file, so we need to be able to handle this. My change handles this problem by treating each strongly-connected component (SCC) as its own unit, and then the graph of SCCs has no cycles. Each SCC has an arbitrariliy chosen representative responsible for linking all messages in the SCC. PiperOrigin-RevId: 761654774
60 lines
1.8 KiB
C++
60 lines
1.8 KiB
C++
// Protocol Buffers - Google's data interchange format
|
|
// Copyright 2023 Google LLC. All rights reserved.
|
|
//
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file or at
|
|
// https://developers.google.com/open-source/licenses/bsd
|
|
|
|
#ifndef UPB_UPB_GENERATOR_PLUGIN_H_
|
|
#define UPB_UPB_GENERATOR_PLUGIN_H_
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <cstring>
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#ifdef _WIN32
|
|
#include <fcntl.h>
|
|
#include <io.h>
|
|
#endif
|
|
|
|
#include "absl/container/flat_hash_set.h"
|
|
#include "absl/strings/string_view.h"
|
|
#include "google/protobuf/compiler/code_generator_lite.h"
|
|
#include "google/protobuf/descriptor.h"
|
|
#include "upb/mem/arena.h"
|
|
#include "upb/mem/arena.hpp"
|
|
#include "upb/reflection/descriptor_bootstrap.h"
|
|
#include "upb_generator/file_layout.h"
|
|
|
|
// Must be last.
|
|
#include "upb/port/def.inc"
|
|
|
|
namespace upb {
|
|
namespace generator {
|
|
|
|
inline std::vector<std::pair<std::string, std::string>> ParseGeneratorParameter(
|
|
const absl::string_view text) {
|
|
std::vector<std::pair<std::string, std::string>> ret;
|
|
google::protobuf::compiler::ParseGeneratorParameter(text, &ret);
|
|
return ret;
|
|
}
|
|
|
|
// Recursively populates the DefPool with the given FileDescriptor.
|
|
void PopulateDefPool(const google::protobuf::FileDescriptor* file, upb::Arena* arena,
|
|
DefPool* pool,
|
|
absl::flat_hash_set<std::string>* files_seen);
|
|
|
|
// Recursively populates the DefPoolPair with the given FileDescriptor.
|
|
void PopulateDefPool(const google::protobuf::FileDescriptor* file, upb::Arena* arena,
|
|
DefPoolPair* pools,
|
|
absl::flat_hash_set<std::string>* files_seen);
|
|
|
|
} // namespace generator
|
|
} // namespace upb
|
|
|
|
#include "upb/port/undef.inc"
|
|
|
|
#endif // UPB_UPB_GENERATOR_PLUGIN_H_
|