From d36c0c538a545fac5d9db6ba65c525246d4efa95 Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Wed, 29 Mar 2017 14:32:48 -0700 Subject: Down-integrate from google3. --- src/google/protobuf/compiler/cpp/cpp_helpers.h | 67 ++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) (limited to 'src/google/protobuf/compiler/cpp/cpp_helpers.h') diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h index 0f297ec8..a744a865 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.h +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h @@ -277,6 +277,73 @@ inline ::google::protobuf::FileOptions_OptimizeMode GetOptimizeFor( : file->options().optimize_for(); } +bool HasWeakFields(const Descriptor* desc); +bool HasWeakFields(const FileDescriptor* desc); + +// Returns true if the "required" restriction check should be ignored for the +// given field. +inline static bool ShouldIgnoreRequiredFieldCheck(const FieldDescriptor* field, + const Options& options) { + return false; +} + +struct SCC { + std::vector descriptors; +}; + +struct MessageAnalysis { + bool is_recursive; + bool contains_cord; + bool contains_extension; + bool contains_required; +}; + +// This class is used in FileGenerator, to ensure linear instead of +// quadratic performance, if we do this per message we would get O(V*(V+E)). +// Logically this is just only used in message.cc, but in the header for +// FileGenerator to help share it. +class LIBPROTOC_EXPORT SCCAnalyzer { + public: + explicit SCCAnalyzer(const Options& options) : options_(options), index_(0) {} + ~SCCAnalyzer() { + for (int i = 0; i < garbage_bin_.size(); i++) delete garbage_bin_[i]; + } + + const SCC* GetSCC(const Descriptor* descriptor) { + if (cache_.count(descriptor)) return cache_[descriptor].scc; + return DFS(descriptor).scc; + } + + MessageAnalysis GetSCCAnalysis(const SCC* scc); + + bool HasRequiredFields(const Descriptor* descriptor) { + MessageAnalysis result = GetSCCAnalysis(GetSCC(descriptor)); + return result.contains_required || result.contains_extension; + } + + private: + struct NodeData { + const SCC* scc; // if null it means its still on the stack + int index; + int lowlink; + }; + + Options options_; + std::map cache_; + std::map analysis_cache_; + std::vector stack_; + int index_; + std::vector garbage_bin_; + + SCC* CreateSCC() { + garbage_bin_.push_back(new SCC()); + return garbage_bin_.back(); + } + + // Tarjan's Strongly Connected Components algo + NodeData DFS(const Descriptor* descriptor); +}; + } // namespace cpp } // namespace compiler } // namespace protobuf -- cgit v1.2.3