Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Unified Diff: third_party/protobuf/src/google/protobuf/descriptor.cc

Issue 1322483002: Revert https://codereview.chromium.org/1291903002 (protobuf roll). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/protobuf/src/google/protobuf/descriptor.cc
diff --git a/third_party/protobuf/src/google/protobuf/descriptor.cc b/third_party/protobuf/src/google/protobuf/descriptor.cc
index 36e42a6df203e9c35f8ec17ef04d2b867ebfbfbc..7c121d9a3fd69e9e9d9d3788ca5413498a42c5a9 100644
--- a/third_party/protobuf/src/google/protobuf/descriptor.cc
+++ b/third_party/protobuf/src/google/protobuf/descriptor.cc
@@ -1,6 +1,6 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
+// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -35,7 +35,6 @@
#include <google/protobuf/stubs/hash.h>
#include <map>
#include <set>
-#include <string>
#include <vector>
#include <algorithm>
#include <limits>
@@ -44,20 +43,17 @@
#include <google/protobuf/descriptor_database.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/dynamic_message.h>
-#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/text_format.h>
#include <google/protobuf/unknown_field_set.h>
#include <google/protobuf/wire_format.h>
-#include <google/protobuf/io/strtod.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/tokenizer.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/once.h>
-#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
-#include <google/protobuf/stubs/map_util.h>
+#include <google/protobuf/stubs/map-util.h>
#include <google/protobuf/stubs/stl_util.h>
#undef PACKAGE // autoheader #defines this. :(
@@ -135,21 +131,6 @@ const char * const FieldDescriptor::kLabelToName[MAX_LABEL + 1] = {
"repeated", // LABEL_REPEATED
};
-const char* FileDescriptor::SyntaxName(FileDescriptor::Syntax syntax) {
- switch (syntax) {
- case SYNTAX_PROTO2:
- return "proto2";
- case SYNTAX_PROTO3:
- return "proto3";
- case SYNTAX_UNKNOWN:
- return "unknown";
- }
- GOOGLE_LOG(FATAL) << "can't reach here.";
- return NULL;
-}
-
-static const char * const kNonLinkedWeakMessageReplacementName = "google.protobuf.Empty";
-
#ifndef _MSC_VER // MSVC doesn't need these and won't even accept them.
const int FieldDescriptor::kMaxNumber;
const int FieldDescriptor::kFirstReservedNumber;
@@ -158,8 +139,8 @@ const int FieldDescriptor::kLastReservedNumber;
namespace {
-string ToCamelCase(const string& input, bool lower_first) {
- bool capitalize_next = !lower_first;
+string ToCamelCase(const string& input) {
+ bool capitalize_next = false;
string result;
result.reserve(input.size());
@@ -180,8 +161,8 @@ string ToCamelCase(const string& input, bool lower_first) {
}
// Lower-case the first letter.
- if (lower_first && !result.empty() && 'A' <= result[0] && result[0] <= 'Z') {
- result[0] = result[0] - 'A' + 'a';
+ if (!result.empty() && 'A' <= result[0] && result[0] <= 'Z') {
+ result[0] = result[0] - 'A' + 'a';
}
return result;
@@ -218,11 +199,9 @@ struct PointerIntegerPairHash {
return reinterpret_cast<intptr_t>(p.first) * ((1 << 16) - 1) + p.second;
}
-#ifdef _MSC_VER
// Used only by MSVC and platforms where hash_map is not available.
static const size_t bucket_size = 4;
static const size_t min_buckets = 8;
-#endif
inline bool operator()(const PairType& a, const PairType& b) const {
return a.first < b.first ||
(a.first == b.first && a.second < b.second);
@@ -241,11 +220,9 @@ struct PointerStringPairHash {
cstring_hash(p.second);
}
-#ifdef _MSC_VER
// Used only by MSVC and platforms where hash_map is not available.
static const size_t bucket_size = 4;
static const size_t min_buckets = 8;
-#endif
inline bool operator()(const PointerStringPair& a,
const PointerStringPair& b) const {
if (a.first < b.first) return true;
@@ -257,14 +234,13 @@ struct PointerStringPairHash {
struct Symbol {
enum Type {
- NULL_SYMBOL, MESSAGE, FIELD, ONEOF, ENUM, ENUM_VALUE, SERVICE, METHOD,
+ NULL_SYMBOL, MESSAGE, FIELD, ENUM, ENUM_VALUE, SERVICE, METHOD,
PACKAGE
};
Type type;
union {
const Descriptor* descriptor;
const FieldDescriptor* field_descriptor;
- const OneofDescriptor* oneof_descriptor;
const EnumDescriptor* enum_descriptor;
const EnumValueDescriptor* enum_value_descriptor;
const ServiceDescriptor* service_descriptor;
@@ -290,7 +266,6 @@ struct Symbol {
CONSTRUCTOR(Descriptor , MESSAGE , descriptor )
CONSTRUCTOR(FieldDescriptor , FIELD , field_descriptor )
- CONSTRUCTOR(OneofDescriptor , ONEOF , oneof_descriptor )
CONSTRUCTOR(EnumDescriptor , ENUM , enum_descriptor )
CONSTRUCTOR(EnumValueDescriptor, ENUM_VALUE, enum_value_descriptor )
CONSTRUCTOR(ServiceDescriptor , SERVICE , service_descriptor )
@@ -303,7 +278,6 @@ struct Symbol {
case NULL_SYMBOL: return NULL;
case MESSAGE : return descriptor ->file();
case FIELD : return field_descriptor ->file();
- case ONEOF : return oneof_descriptor ->containing_type()->file();
case ENUM : return enum_descriptor ->file();
case ENUM_VALUE : return enum_value_descriptor->type()->file();
case SERVICE : return service_descriptor ->file();
@@ -340,36 +314,6 @@ typedef hash_map<EnumIntPair, const EnumValueDescriptor*,
// for that.
typedef map<DescriptorIntPair, const FieldDescriptor*>
ExtensionsGroupedByDescriptorMap;
-typedef hash_map<string, const SourceCodeInfo_Location*> LocationsByPathMap;
-
-set<string>* allowed_proto3_extendees_ = NULL;
-GOOGLE_PROTOBUF_DECLARE_ONCE(allowed_proto3_extendees_init_);
-
-void DeleteAllowedProto3Extendee() {
- delete allowed_proto3_extendees_;
-}
-
-void InitAllowedProto3Extendee() {
- allowed_proto3_extendees_ = new set<string>;
- allowed_proto3_extendees_->insert("google.protobuf.FileOptions");
- allowed_proto3_extendees_->insert("google.protobuf.MessageOptions");
- allowed_proto3_extendees_->insert("google.protobuf.FieldOptions");
- allowed_proto3_extendees_->insert("google.protobuf.EnumOptions");
- allowed_proto3_extendees_->insert("google.protobuf.EnumValueOptions");
- allowed_proto3_extendees_->insert("google.protobuf.ServiceOptions");
- allowed_proto3_extendees_->insert("google.protobuf.MethodOptions");
- google::protobuf::internal::OnShutdown(&DeleteAllowedProto3Extendee);
-}
-
-// Checks whether the extendee type is allowed in proto3.
-// Only extensions to descriptor options are allowed. We use name comparison
-// instead of comparing the descriptor directly because the extensions may be
-// defined in a different pool.
-bool AllowedExtendeeInProto3(const string& name) {
- ::google::protobuf::GoogleOnceInit(&allowed_proto3_extendees_init_, &InitAllowedProto3Extendee);
- return allowed_proto3_extendees_->find(name) !=
- allowed_proto3_extendees_->end();
-}
} // anonymous namespace
@@ -424,18 +368,10 @@ class DescriptorPool::Tables {
vector<string> pending_files_;
// A set of files which we have tried to load from the fallback database
- // and encountered errors. We will not attempt to load them again during
- // execution of the current public API call, but for compatibility with
- // legacy clients, this is cleared at the beginning of each public API call.
+ // and encountered errors. We will not attempt to load them again.
// Not used when fallback_database_ == NULL.
hash_set<string> known_bad_files_;
- // A set of symbols which we have tried to load from the fallback database
- // and encountered errors. We will not attempt to load them again during
- // execution of the current public API call, but for compatibility with
- // legacy clients, this is cleared at the beginning of each public API call.
- hash_set<string> known_bad_symbols_;
-
// The set of descriptors for which we've already loaded the full
// set of extensions numbers from fallback_database_.
hash_set<const Descriptor*> extensions_loaded_from_db_;
@@ -452,7 +388,7 @@ class DescriptorPool::Tables {
// declaring Symbol in descriptor.h, which would drag all kinds of other
// stuff into the header. Yay C++.
Symbol FindByNameHelper(
- const DescriptorPool* pool, const string& name);
+ const DescriptorPool* pool, const string& name) const;
// These return NULL if not found.
inline const FileDescriptor* FindFile(const string& key) const;
@@ -576,9 +512,6 @@ class FileDescriptorTables {
const void* parent, const string& camelcase_name) const;
inline const EnumValueDescriptor* FindEnumValueByNumber(
const EnumDescriptor* parent, int number) const;
- // This creates a new EnumValueDescriptor if not found, in a thread-safe way.
- inline const EnumValueDescriptor* FindEnumValueByNumberCreatingIfUnknown(
- const EnumDescriptor* parent, int number) const;
// -----------------------------------------------------------------
// Adding items.
@@ -596,40 +529,17 @@ class FileDescriptorTables {
// fails because we allow duplicates; the first field by the name wins.
void AddFieldByStylizedNames(const FieldDescriptor* field);
- // Populates p->first->locations_by_path_ from p->second.
- // Unusual signature dictated by GoogleOnceDynamic.
- static void BuildLocationsByPath(
- pair<const FileDescriptorTables*, const SourceCodeInfo*>* p);
-
- // Returns the location denoted by the specified path through info,
- // or NULL if not found.
- // The value of info must be that of the corresponding FileDescriptor.
- // (Conceptually a pure function, but stateful as an optimisation.)
- const SourceCodeInfo_Location* GetSourceLocation(
- const vector<int>& path, const SourceCodeInfo* info) const;
-
private:
SymbolsByParentMap symbols_by_parent_;
FieldsByNameMap fields_by_lowercase_name_;
FieldsByNameMap fields_by_camelcase_name_;
FieldsByNumberMap fields_by_number_; // Not including extensions.
EnumValuesByNumberMap enum_values_by_number_;
- mutable EnumValuesByNumberMap unknown_enum_values_by_number_
- GOOGLE_GUARDED_BY(unknown_enum_values_mu_);
-
- // Populated on first request to save space, hence constness games.
- mutable GoogleOnceDynamic locations_by_path_once_;
- mutable LocationsByPathMap locations_by_path_;
-
- // Mutex to protect the unknown-enum-value map due to dynamic
- // EnumValueDescriptor creation on unknown values.
- mutable Mutex unknown_enum_values_mu_;
};
DescriptorPool::Tables::Tables()
// Start some hash_map and hash_set objects with a small # of buckets
: known_bad_files_(3),
- known_bad_symbols_(3),
extensions_loaded_from_db_(3),
symbols_by_name_(3),
files_by_name_(3) {}
@@ -653,8 +563,7 @@ FileDescriptorTables::FileDescriptorTables()
fields_by_lowercase_name_(3),
fields_by_camelcase_name_(3),
fields_by_number_(3),
- enum_values_by_number_(3),
- unknown_enum_values_by_number_(3) {
+ enum_values_by_number_(3) {
}
FileDescriptorTables::~FileDescriptorTables() {}
@@ -754,10 +663,8 @@ inline Symbol FileDescriptorTables::FindNestedSymbolOfType(
}
Symbol DescriptorPool::Tables::FindByNameHelper(
- const DescriptorPool* pool, const string& name) {
+ const DescriptorPool* pool, const string& name) const {
MutexLockMaybe lock(pool->mutex_);
- known_bad_symbols_.clear();
- known_bad_files_.clear();
Symbol result = FindSymbol(name);
if (result.IsNull() && pool->underlay_ != NULL) {
@@ -783,7 +690,7 @@ inline const FileDescriptor* DescriptorPool::Tables::FindFile(
inline const FieldDescriptor* FileDescriptorTables::FindFieldByNumber(
const Descriptor* parent, int number) const {
- return FindPtrOrNull(fields_by_number_, std::make_pair(parent, number));
+ return FindPtrOrNull(fields_by_number_, make_pair(parent, number));
}
inline const FieldDescriptor* FileDescriptorTables::FindFieldByLowercaseName(
@@ -800,71 +707,18 @@ inline const FieldDescriptor* FileDescriptorTables::FindFieldByCamelcaseName(
inline const EnumValueDescriptor* FileDescriptorTables::FindEnumValueByNumber(
const EnumDescriptor* parent, int number) const {
- return FindPtrOrNull(enum_values_by_number_, std::make_pair(parent, number));
-}
-
-inline const EnumValueDescriptor*
-FileDescriptorTables::FindEnumValueByNumberCreatingIfUnknown(
- const EnumDescriptor* parent, int number) const {
- // First try, with map of compiled-in values.
- {
- const EnumValueDescriptor* desc =
- FindPtrOrNull(enum_values_by_number_, std::make_pair(parent, number));
- if (desc != NULL) {
- return desc;
- }
- }
- // Second try, with reader lock held on unknown enum values: common case.
- {
- ReaderMutexLock l(&unknown_enum_values_mu_);
- const EnumValueDescriptor* desc = FindPtrOrNull(
- unknown_enum_values_by_number_, std::make_pair(parent, number));
- if (desc != NULL) {
- return desc;
- }
- }
- // If not found, try again with writer lock held, and create new descriptor if
- // necessary.
- {
- WriterMutexLock l(&unknown_enum_values_mu_);
- const EnumValueDescriptor* desc = FindPtrOrNull(
- unknown_enum_values_by_number_, std::make_pair(parent, number));
- if (desc != NULL) {
- return desc;
- }
-
- // Create an EnumValueDescriptor dynamically. We don't insert it into the
- // EnumDescriptor (it's not a part of the enum as originally defined), but
- // we do insert it into the table so that we can return the same pointer
- // later.
- string enum_value_name = StringPrintf(
- "UNKNOWN_ENUM_VALUE_%s_%d", parent->name().c_str(), number);
- DescriptorPool::Tables* tables =
- const_cast<DescriptorPool::Tables*>(DescriptorPool::generated_pool()->
- tables_.get());
- EnumValueDescriptor* result = tables->Allocate<EnumValueDescriptor>();
- result->name_ = tables->AllocateString(enum_value_name);
- result->full_name_ = tables->AllocateString(parent->full_name() +
- "." + enum_value_name);
- result->number_ = number;
- result->type_ = parent;
- result->options_ = &EnumValueOptions::default_instance();
- InsertIfNotPresent(&unknown_enum_values_by_number_,
- std::make_pair(parent, number), result);
- return result;
- }
+ return FindPtrOrNull(enum_values_by_number_, make_pair(parent, number));
}
-
inline const FieldDescriptor* DescriptorPool::Tables::FindExtension(
const Descriptor* extendee, int number) {
- return FindPtrOrNull(extensions_, std::make_pair(extendee, number));
+ return FindPtrOrNull(extensions_, make_pair(extendee, number));
}
inline void DescriptorPool::Tables::FindAllExtensions(
const Descriptor* extendee, vector<const FieldDescriptor*>* out) const {
ExtensionsGroupedByDescriptorMap::const_iterator it =
- extensions_.lower_bound(std::make_pair(extendee, 0));
+ extensions_.lower_bound(make_pair(extendee, 0));
for (; it != extensions_.end() && it->first.first == extendee; ++it) {
out->push_back(it->second);
}
@@ -957,7 +811,7 @@ string* DescriptorPool::Tables::AllocateString(const string& value) {
}
template<typename Type>
-Type* DescriptorPool::Tables::AllocateMessage(Type* /* dummy */) {
+Type* DescriptorPool::Tables::AllocateMessage(Type* dummy) {
Type* result = new Type;
messages_.push_back(result);
return result;
@@ -981,22 +835,6 @@ void* DescriptorPool::Tables::AllocateBytes(int size) {
return result;
}
-void FileDescriptorTables::BuildLocationsByPath(
- pair<const FileDescriptorTables*, const SourceCodeInfo*>* p) {
- for (int i = 0, len = p->second->location_size(); i < len; ++i) {
- const SourceCodeInfo_Location* loc = &p->second->location().Get(i);
- p->first->locations_by_path_[Join(loc->path(), ",")] = loc;
- }
-}
-
-const SourceCodeInfo_Location* FileDescriptorTables::GetSourceLocation(
- const vector<int>& path, const SourceCodeInfo* info) const {
- pair<const FileDescriptorTables*, const SourceCodeInfo*> p(
- std::make_pair(this, info));
- locations_by_path_once_.Init(&FileDescriptorTables::BuildLocationsByPath, &p);
- return FindPtrOrNull(locations_by_path_, Join(path, ","));
-}
-
// ===================================================================
// DescriptorPool
@@ -1009,8 +847,7 @@ DescriptorPool::DescriptorPool()
underlay_(NULL),
tables_(new Tables),
enforce_dependencies_(true),
- allow_unknown_(false),
- enforce_weak_(false) {}
+ allow_unknown_(false) {}
DescriptorPool::DescriptorPool(DescriptorDatabase* fallback_database,
ErrorCollector* error_collector)
@@ -1020,8 +857,7 @@ DescriptorPool::DescriptorPool(DescriptorDatabase* fallback_database,
underlay_(NULL),
tables_(new Tables),
enforce_dependencies_(true),
- allow_unknown_(false),
- enforce_weak_(false) {
+ allow_unknown_(false) {
}
DescriptorPool::DescriptorPool(const DescriptorPool* underlay)
@@ -1031,8 +867,7 @@ DescriptorPool::DescriptorPool(const DescriptorPool* underlay)
underlay_(underlay),
tables_(new Tables),
enforce_dependencies_(true),
- allow_unknown_(false),
- enforce_weak_(false) {}
+ allow_unknown_(false) {}
DescriptorPool::~DescriptorPool() {
if (mutex_ != NULL) delete mutex_;
@@ -1045,14 +880,6 @@ void DescriptorPool::InternalDontEnforceDependencies() {
enforce_dependencies_ = false;
}
-void DescriptorPool::AddUnusedImportTrackFile(const string& file_name) {
- unused_import_track_files_.insert(file_name);
-}
-
-void DescriptorPool::ClearUnusedImportTrackFiles() {
- unused_import_track_files_.clear();
-}
-
bool DescriptorPool::InternalIsFileLoaded(const string& filename) const {
MutexLockMaybe lock(mutex_);
return tables_->FindFile(filename) != NULL;
@@ -1134,8 +961,6 @@ void DescriptorPool::InternalAddGeneratedFile(
const FileDescriptor* DescriptorPool::FindFileByName(const string& name) const {
MutexLockMaybe lock(mutex_);
- tables_->known_bad_symbols_.clear();
- tables_->known_bad_files_.clear();
const FileDescriptor* result = tables_->FindFile(name);
if (result != NULL) return result;
if (underlay_ != NULL) {
@@ -1152,8 +977,6 @@ const FileDescriptor* DescriptorPool::FindFileByName(const string& name) const {
const FileDescriptor* DescriptorPool::FindFileContainingSymbol(
const string& symbol_name) const {
MutexLockMaybe lock(mutex_);
- tables_->known_bad_symbols_.clear();
- tables_->known_bad_files_.clear();
Symbol result = tables_->FindSymbol(symbol_name);
if (!result.IsNull()) return result.GetFile();
if (underlay_ != NULL) {
@@ -1196,12 +1019,6 @@ const FieldDescriptor* DescriptorPool::FindExtensionByName(
}
}
-const OneofDescriptor* DescriptorPool::FindOneofByName(
- const string& name) const {
- Symbol result = tables_->FindByNameHelper(this, name);
- return (result.type == Symbol::ONEOF) ? result.oneof_descriptor : NULL;
-}
-
const EnumDescriptor* DescriptorPool::FindEnumTypeByName(
const string& name) const {
Symbol result = tables_->FindByNameHelper(this, name);
@@ -1230,8 +1047,6 @@ const MethodDescriptor* DescriptorPool::FindMethodByName(
const FieldDescriptor* DescriptorPool::FindExtensionByNumber(
const Descriptor* extendee, int number) const {
MutexLockMaybe lock(mutex_);
- tables_->known_bad_symbols_.clear();
- tables_->known_bad_files_.clear();
const FieldDescriptor* result = tables_->FindExtension(extendee, number);
if (result != NULL) {
return result;
@@ -1252,8 +1067,6 @@ const FieldDescriptor* DescriptorPool::FindExtensionByNumber(
void DescriptorPool::FindAllExtensions(
const Descriptor* extendee, vector<const FieldDescriptor*>* out) const {
MutexLockMaybe lock(mutex_);
- tables_->known_bad_symbols_.clear();
- tables_->known_bad_files_.clear();
// Initialize tables_->extensions_ from the fallback database first
// (but do this only once per descriptor).
@@ -1278,7 +1091,6 @@ void DescriptorPool::FindAllExtensions(
}
}
-
// -------------------------------------------------------------------
const FieldDescriptor*
@@ -1325,17 +1137,6 @@ Descriptor::FindFieldByName(const string& key) const {
}
}
-const OneofDescriptor*
-Descriptor::FindOneofByName(const string& key) const {
- Symbol result =
- file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ONEOF);
- if (!result.IsNull()) {
- return result.oneof_descriptor;
- } else {
- return NULL;
- }
-}
-
const FieldDescriptor*
Descriptor::FindExtensionByName(const string& key) const {
Symbol result =
@@ -1418,11 +1219,6 @@ EnumDescriptor::FindValueByNumber(int key) const {
return file()->tables_->FindEnumValueByNumber(this, key);
}
-const EnumValueDescriptor*
-EnumDescriptor::FindValueByNumberCreatingIfUnknown(int key) const {
- return file()->tables_->FindEnumValueByNumberCreatingIfUnknown(this, key);
-}
-
const MethodDescriptor*
ServiceDescriptor::FindMethodByName(const string& key) const {
Symbol result =
@@ -1505,29 +1301,16 @@ FileDescriptor::FindExtensionByCamelcaseName(const string& key) const {
}
}
-const Descriptor::ExtensionRange*
-Descriptor::FindExtensionRangeContainingNumber(int number) const {
+bool Descriptor::IsExtensionNumber(int number) const {
// Linear search should be fine because we don't expect a message to have
// more than a couple extension ranges.
for (int i = 0; i < extension_range_count(); i++) {
if (number >= extension_range(i)->start &&
number < extension_range(i)->end) {
- return extension_range(i);
- }
- }
- return NULL;
-}
-
-const Descriptor::ReservedRange*
-Descriptor::FindReservedRangeContainingNumber(int number) const {
- // TODO(chrisn): Consider a non-linear search.
- for (int i = 0; i < reserved_range_count(); i++) {
- if (number >= reserved_range(i)->start &&
- number < reserved_range(i)->end) {
- return reserved_range(i);
+ return true;
}
}
- return NULL;
+ return false;
}
// -------------------------------------------------------------------
@@ -1543,6 +1326,7 @@ bool DescriptorPool::TryFindFileInFallbackDatabase(const string& name) const {
tables_->known_bad_files_.insert(name);
return false;
}
+
return true;
}
@@ -1571,38 +1355,36 @@ bool DescriptorPool::IsSubSymbolOfBuiltType(const string& name) const {
bool DescriptorPool::TryFindSymbolInFallbackDatabase(const string& name) const {
if (fallback_database_ == NULL) return false;
- if (tables_->known_bad_symbols_.count(name) > 0) return false;
+ // We skip looking in the fallback database if the name is a sub-symbol of
+ // any descriptor that already exists in the descriptor pool (except for
+ // package descriptors). This is valid because all symbols except for
+ // packages are defined in a single file, so if the symbol exists then we
+ // should already have its definition.
+ //
+ // The other reason to do this is to support "overriding" type definitions
+ // by merging two databases that define the same type. (Yes, people do
+ // this.) The main difficulty with making this work is that
+ // FindFileContainingSymbol() is allowed to return both false positives
+ // (e.g., SimpleDescriptorDatabase, UpgradedDescriptorDatabase) and false
+ // negatives (e.g. ProtoFileParser, SourceTreeDescriptorDatabase). When two
+ // such databases are merged, looking up a non-existent sub-symbol of a type
+ // that already exists in the descriptor pool can result in an attempt to
+ // load multiple definitions of the same type. The check below avoids this.
+ if (IsSubSymbolOfBuiltType(name)) return false;
FileDescriptorProto file_proto;
- if (// We skip looking in the fallback database if the name is a sub-symbol
- // of any descriptor that already exists in the descriptor pool (except
- // for package descriptors). This is valid because all symbols except
- // for packages are defined in a single file, so if the symbol exists
- // then we should already have its definition.
- //
- // The other reason to do this is to support "overriding" type
- // definitions by merging two databases that define the same type. (Yes,
- // people do this.) The main difficulty with making this work is that
- // FindFileContainingSymbol() is allowed to return both false positives
- // (e.g., SimpleDescriptorDatabase, UpgradedDescriptorDatabase) and false
- // negatives (e.g. ProtoFileParser, SourceTreeDescriptorDatabase).
- // When two such databases are merged, looking up a non-existent
- // sub-symbol of a type that already exists in the descriptor pool can
- // result in an attempt to load multiple definitions of the same type.
- // The check below avoids this.
- IsSubSymbolOfBuiltType(name)
-
- // Look up file containing this symbol in fallback database.
- || !fallback_database_->FindFileContainingSymbol(name, &file_proto)
-
- // Check if we've already built this file. If so, it apparently doesn't
- // contain the symbol we're looking for. Some DescriptorDatabases
- // return false positives.
- || tables_->FindFile(file_proto.name()) != NULL
-
- // Build the file.
- || BuildFileFromDatabase(file_proto) == NULL) {
- tables_->known_bad_symbols_.insert(name);
+ if (!fallback_database_->FindFileContainingSymbol(name, &file_proto)) {
+ return false;
+ }
+
+ if (tables_->FindFile(file_proto.name()) != NULL) {
+ // We've already loaded this file, and it apparently doesn't contain the
+ // symbol we're looking for. Some DescriptorDatabases return false
+ // positives.
+ return false;
+ }
+
+ if (BuildFileFromDatabase(file_proto) == NULL) {
return false;
}
@@ -1635,10 +1417,6 @@ bool DescriptorPool::TryFindExtensionInFallbackDatabase(
// ===================================================================
-bool FieldDescriptor::is_map() const {
- return type() == TYPE_MESSAGE && message_type()->options().map_entry();
-}
-
string FieldDescriptor::DefaultValueAsString(bool quote_string_type) const {
GOOGLE_CHECK(has_default_value()) << "No default value";
switch (cpp_type()) {
@@ -1690,8 +1468,6 @@ string FieldDescriptor::DefaultValueAsString(bool quote_string_type) const {
void FileDescriptor::CopyTo(FileDescriptorProto* proto) const {
proto->set_name(name());
if (!package().empty()) proto->set_package(package());
- // TODO(liujisi): Also populate when syntax="proto2".
- if (syntax() == SYNTAX_PROTO3) proto->set_syntax(SyntaxName(syntax()));
for (int i = 0; i < dependency_count(); i++) {
proto->add_dependency(dependency(i)->name());
@@ -1724,8 +1500,7 @@ void FileDescriptor::CopyTo(FileDescriptorProto* proto) const {
}
void FileDescriptor::CopySourceCodeInfoTo(FileDescriptorProto* proto) const {
- if (source_code_info_ &&
- source_code_info_ != &SourceCodeInfo::default_instance()) {
+ if (source_code_info_ != &SourceCodeInfo::default_instance()) {
proto->mutable_source_code_info()->CopyFrom(*source_code_info_);
}
}
@@ -1736,9 +1511,6 @@ void Descriptor::CopyTo(DescriptorProto* proto) const {
for (int i = 0; i < field_count(); i++) {
field(i)->CopyTo(proto->add_field());
}
- for (int i = 0; i < oneof_decl_count(); i++) {
- oneof_decl(i)->CopyTo(proto->add_oneof_decl());
- }
for (int i = 0; i < nested_type_count(); i++) {
nested_type(i)->CopyTo(proto->add_nested_type());
}
@@ -1753,14 +1525,6 @@ void Descriptor::CopyTo(DescriptorProto* proto) const {
for (int i = 0; i < extension_count(); i++) {
extension(i)->CopyTo(proto->add_extension());
}
- for (int i = 0; i < reserved_range_count(); i++) {
- DescriptorProto::ReservedRange* range = proto->add_reserved_range();
- range->set_start(reserved_range(i)->start);
- range->set_end(reserved_range(i)->end);
- }
- for (int i = 0; i < reserved_name_count(); i++) {
- proto->add_reserved_name(reserved_name(i));
- }
if (&options() != &MessageOptions::default_instance()) {
proto->mutable_options()->CopyFrom(options());
@@ -1807,19 +1571,11 @@ void FieldDescriptor::CopyTo(FieldDescriptorProto* proto) const {
proto->set_default_value(DefaultValueAsString(false));
}
- if (containing_oneof() != NULL && !is_extension()) {
- proto->set_oneof_index(containing_oneof()->index());
- }
-
if (&options() != &FieldOptions::default_instance()) {
proto->mutable_options()->CopyFrom(options());
}
}
-void OneofDescriptor::CopyTo(OneofDescriptorProto* proto) const {
- proto->set_name(name());
-}
-
void EnumDescriptor::CopyTo(EnumDescriptorProto* proto) const {
proto->set_name(name());
@@ -1869,13 +1625,6 @@ void MethodDescriptor::CopyTo(MethodDescriptorProto* proto) const {
if (&options() != &MethodOptions::default_instance()) {
proto->mutable_options()->CopyFrom(options());
}
-
- if (client_streaming_) {
- proto->set_client_streaming(true);
- }
- if (server_streaming_) {
- proto->set_server_streaming(true);
- }
}
// DebugString methods ===============================================
@@ -1930,7 +1679,7 @@ bool RetrieveOptions(int depth,
bool FormatBracketedOptions(int depth, const Message &options, string *output) {
vector<string> all_options;
if (RetrieveOptions(depth, options, &all_options)) {
- output->append(Join(all_options, ", "));
+ output->append(JoinStrings(all_options, ", "));
}
return !all_options.empty();
}
@@ -1948,92 +1697,10 @@ bool FormatLineOptions(int depth, const Message &options, string *output) {
return !all_options.empty();
}
-class SourceLocationCommentPrinter {
- public:
- template<typename DescType>
- SourceLocationCommentPrinter(const DescType* desc,
- const string& prefix,
- const DebugStringOptions& options)
- : options_(options), prefix_(prefix) {
- // Perform the SourceLocation lookup only if we're including user comments,
- // because the lookup is fairly expensive.
- have_source_loc_ = options.include_comments &&
- desc->GetSourceLocation(&source_loc_);
- }
- SourceLocationCommentPrinter(const FileDescriptor* file,
- const vector<int>& path,
- const string& prefix,
- const DebugStringOptions& options)
- : options_(options), prefix_(prefix) {
- // Perform the SourceLocation lookup only if we're including user comments,
- // because the lookup is fairly expensive.
- have_source_loc_ = options.include_comments &&
- file->GetSourceLocation(path, &source_loc_);
- }
- void AddPreComment(string* output) {
- if (have_source_loc_) {
- // Detached leading comments.
- for (int i = 0 ; i < source_loc_.leading_detached_comments.size(); ++i) {
- *output += FormatComment(source_loc_.leading_detached_comments[i]);
- *output += "\n";
- }
- // Attached leading comments.
- if (!source_loc_.leading_comments.empty()) {
- *output += FormatComment(source_loc_.leading_comments);
- }
- }
- }
- void AddPostComment(string* output) {
- if (have_source_loc_ && source_loc_.trailing_comments.size() > 0) {
- *output += FormatComment(source_loc_.trailing_comments);
- }
- }
-
- // Format comment such that each line becomes a full-line C++-style comment in
- // the DebugString() output.
- string FormatComment(const string& comment_text) {
- string stripped_comment = comment_text;
- StripWhitespace(&stripped_comment);
- vector<string> lines = Split(stripped_comment, "\n");
- string output;
- for (int i = 0; i < lines.size(); ++i) {
- const string& line = lines[i];
- strings::SubstituteAndAppend(&output, "$0// $1\n", prefix_, line);
- }
- return output;
- }
-
- private:
- bool have_source_loc_;
- SourceLocation source_loc_;
- DebugStringOptions options_;
- string prefix_;
-};
-
} // anonymous namespace
string FileDescriptor::DebugString() const {
- DebugStringOptions options; // default options
- return DebugStringWithOptions(options);
-}
-
-string FileDescriptor::DebugStringWithOptions(
- const DebugStringOptions& debug_string_options) const {
- string contents;
- {
- vector<int> path;
- path.push_back(FileDescriptorProto::kSyntaxFieldNumber);
- SourceLocationCommentPrinter syntax_comment(
- this, path, "", debug_string_options);
- syntax_comment.AddPreComment(&contents);
- strings::SubstituteAndAppend(&contents, "syntax = \"$0\";\n\n",
- SyntaxName(syntax()));
- syntax_comment.AddPostComment(&contents);
- }
-
- SourceLocationCommentPrinter
- comment_printer(this, "", debug_string_options);
- comment_printer.AddPreComment(&contents);
+ string contents = "syntax = \"proto2\";\n\n";
set<int> public_dependencies;
set<int> weak_dependencies;
@@ -2056,13 +1723,7 @@ string FileDescriptor::DebugStringWithOptions(
}
if (!package().empty()) {
- vector<int> path;
- path.push_back(FileDescriptorProto::kPackageFieldNumber);
- SourceLocationCommentPrinter package_comment(
- this, path, "", debug_string_options);
- package_comment.AddPreComment(&contents);
strings::SubstituteAndAppend(&contents, "package $0;\n\n", package());
- package_comment.AddPostComment(&contents);
}
if (FormatLineOptions(0, options(), &contents)) {
@@ -2070,7 +1731,7 @@ string FileDescriptor::DebugStringWithOptions(
}
for (int i = 0; i < enum_type_count(); i++) {
- enum_type(i)->DebugString(0, &contents, debug_string_options);
+ enum_type(i)->DebugString(0, &contents);
contents.append("\n");
}
@@ -2085,14 +1746,15 @@ string FileDescriptor::DebugStringWithOptions(
for (int i = 0; i < message_type_count(); i++) {
if (groups.count(message_type(i)) == 0) {
- message_type(i)->DebugString(0, &contents, debug_string_options,
- /* include_opening_clause */ true);
+ strings::SubstituteAndAppend(&contents, "message $0",
+ message_type(i)->name());
+ message_type(i)->DebugString(0, &contents);
contents.append("\n");
}
}
for (int i = 0; i < service_count(); i++) {
- service(i)->DebugString(&contents, debug_string_options);
+ service(i)->DebugString(&contents);
contents.append("\n");
}
@@ -2104,46 +1766,23 @@ string FileDescriptor::DebugStringWithOptions(
strings::SubstituteAndAppend(&contents, "extend .$0 {\n",
containing_type->full_name());
}
- extension(i)->DebugString(1, FieldDescriptor::PRINT_LABEL, &contents,
- debug_string_options);
+ extension(i)->DebugString(1, &contents);
}
if (extension_count() > 0) contents.append("}\n\n");
- comment_printer.AddPostComment(&contents);
-
return contents;
}
string Descriptor::DebugString() const {
- DebugStringOptions options; // default options
- return DebugStringWithOptions(options);
-}
-
-string Descriptor::DebugStringWithOptions(
- const DebugStringOptions& options) const {
string contents;
- DebugString(0, &contents, options, /* include_opening_clause */ true);
+ strings::SubstituteAndAppend(&contents, "message $0", name());
+ DebugString(0, &contents);
return contents;
}
-void Descriptor::DebugString(int depth, string *contents,
- const DebugStringOptions&
- debug_string_options,
- bool include_opening_clause) const {
- if (options().map_entry()) {
- // Do not generate debug string for auto-generated map-entry type.
- return;
- }
+void Descriptor::DebugString(int depth, string *contents) const {
string prefix(depth * 2, ' ');
++depth;
-
- SourceLocationCommentPrinter
- comment_printer(this, prefix, debug_string_options);
- comment_printer.AddPreComment(contents);
-
- if (include_opening_clause) {
- strings::SubstituteAndAppend(contents, "$0message $1", prefix, name());
- }
contents->append(" {\n");
FormatLineOptions(depth, options(), contents);
@@ -2165,22 +1804,16 @@ void Descriptor::DebugString(int depth, string *contents,
for (int i = 0; i < nested_type_count(); i++) {
if (groups.count(nested_type(i)) == 0) {
- nested_type(i)->DebugString(depth, contents, debug_string_options,
- /* include_opening_clause */ true);
+ strings::SubstituteAndAppend(contents, "$0 message $1",
+ prefix, nested_type(i)->name());
+ nested_type(i)->DebugString(depth, contents);
}
}
for (int i = 0; i < enum_type_count(); i++) {
- enum_type(i)->DebugString(depth, contents, debug_string_options);
+ enum_type(i)->DebugString(depth, contents);
}
for (int i = 0; i < field_count(); i++) {
- if (field(i)->containing_oneof() == NULL) {
- field(i)->DebugString(depth, FieldDescriptor::PRINT_LABEL, contents,
- debug_string_options);
- } else if (field(i)->containing_oneof()->field(0) == field(i)) {
- // This is the first field in this oneof, so print the whole oneof.
- field(i)->containing_oneof()->DebugString(depth, contents,
- debug_string_options);
- }
+ field(i)->DebugString(depth, contents);
}
for (int i = 0; i < extension_range_count(); i++) {
@@ -2199,47 +1832,15 @@ void Descriptor::DebugString(int depth, string *contents,
strings::SubstituteAndAppend(contents, "$0 extend .$1 {\n",
prefix, containing_type->full_name());
}
- extension(i)->DebugString(
- depth + 1, FieldDescriptor::PRINT_LABEL, contents,
- debug_string_options);
+ extension(i)->DebugString(depth + 1, contents);
}
if (extension_count() > 0)
strings::SubstituteAndAppend(contents, "$0 }\n", prefix);
- if (reserved_range_count() > 0) {
- strings::SubstituteAndAppend(contents, "$0 reserved ", prefix);
- for (int i = 0; i < reserved_range_count(); i++) {
- const Descriptor::ReservedRange* range = reserved_range(i);
- if (range->end == range->start + 1) {
- strings::SubstituteAndAppend(contents, "$0, ", range->start);
- } else {
- strings::SubstituteAndAppend(contents, "$0 to $1, ",
- range->start, range->end - 1);
- }
- }
- contents->replace(contents->size() - 2, 2, ";\n");
- }
-
- if (reserved_name_count() > 0) {
- strings::SubstituteAndAppend(contents, "$0 reserved ", prefix);
- for (int i = 0; i < reserved_name_count(); i++) {
- strings::SubstituteAndAppend(contents, "\"$0\", ",
- CEscape(reserved_name(i)));
- }
- contents->replace(contents->size() - 2, 2, ";\n");
- }
-
strings::SubstituteAndAppend(contents, "$0}\n", prefix);
- comment_printer.AddPostComment(contents);
}
string FieldDescriptor::DebugString() const {
- DebugStringOptions options; // default options
- return DebugStringWithOptions(options);
-}
-
-string FieldDescriptor::DebugStringWithOptions(
- const DebugStringOptions& debug_string_options) const {
string contents;
int depth = 0;
if (is_extension()) {
@@ -2247,56 +1848,30 @@ string FieldDescriptor::DebugStringWithOptions(
containing_type()->full_name());
depth = 1;
}
- DebugString(depth, PRINT_LABEL, &contents, debug_string_options);
+ DebugString(depth, &contents);
if (is_extension()) {
- contents.append("}\n");
+ contents.append("}\n");
}
return contents;
}
-// The field type string used in FieldDescriptor::DebugString()
-string FieldDescriptor::FieldTypeNameDebugString() const {
- switch(type()) {
+void FieldDescriptor::DebugString(int depth, string *contents) const {
+ string prefix(depth * 2, ' ');
+ string field_type;
+ switch (type()) {
case TYPE_MESSAGE:
- return "." + message_type()->full_name();
+ field_type = "." + message_type()->full_name();
+ break;
case TYPE_ENUM:
- return "." + enum_type()->full_name();
+ field_type = "." + enum_type()->full_name();
+ break;
default:
- return kTypeToName[type()];
- }
-}
-
-void FieldDescriptor::DebugString(int depth,
- PrintLabelFlag print_label_flag,
- string *contents,
- const DebugStringOptions&
- debug_string_options) const {
- string prefix(depth * 2, ' ');
- string field_type;
-
- // Special case map fields.
- if (is_map()) {
- strings::SubstituteAndAppend(
- &field_type, "map<$0, $1>",
- message_type()->field(0)->FieldTypeNameDebugString(),
- message_type()->field(1)->FieldTypeNameDebugString());
- } else {
- field_type = FieldTypeNameDebugString();
- }
-
- string label;
- if (print_label_flag == PRINT_LABEL && !is_map()) {
- label = kLabelToName[this->label()];
- label.push_back(' ');
+ field_type = kTypeToName[type()];
}
- SourceLocationCommentPrinter
- comment_printer(this, prefix, debug_string_options);
- comment_printer.AddPreComment(contents);
-
- strings::SubstituteAndAppend(contents, "$0$1$2 $3 = $4",
+ strings::SubstituteAndAppend(contents, "$0$1 $2 $3 = $4",
prefix,
- label,
+ kLabelToName[label()],
field_type,
type() == TYPE_GROUP ? message_type()->name() :
name(),
@@ -2321,109 +1896,40 @@ void FieldDescriptor::DebugString(int depth,
}
if (type() == TYPE_GROUP) {
- if (debug_string_options.elide_group_body) {
- contents->append(" { ... };\n");
- } else {
- message_type()->DebugString(depth, contents, debug_string_options,
- /* include_opening_clause */ false);
- }
+ message_type()->DebugString(depth, contents);
} else {
contents->append(";\n");
}
-
- comment_printer.AddPostComment(contents);
-}
-
-string OneofDescriptor::DebugString() const {
- DebugStringOptions options; // default values
- return DebugStringWithOptions(options);
-}
-
-string OneofDescriptor::DebugStringWithOptions(
- const DebugStringOptions& options) const {
- string contents;
- DebugString(0, &contents, options);
- return contents;
-}
-
-void OneofDescriptor::DebugString(int depth, string* contents,
- const DebugStringOptions&
- debug_string_options) const {
- string prefix(depth * 2, ' ');
- ++depth;
- SourceLocationCommentPrinter
- comment_printer(this, prefix, debug_string_options);
- comment_printer.AddPreComment(contents);
- strings::SubstituteAndAppend(
- contents, "$0 oneof $1 {", prefix, name());
- if (debug_string_options.elide_oneof_body) {
- contents->append(" ... }\n");
- } else {
- for (int i = 0; i < field_count(); i++) {
- field(i)->DebugString(depth, FieldDescriptor::OMIT_LABEL, contents,
- debug_string_options);
- }
- strings::SubstituteAndAppend(contents, "$0}\n", prefix);
- }
- comment_printer.AddPostComment(contents);
}
string EnumDescriptor::DebugString() const {
- DebugStringOptions options; // default values
- return DebugStringWithOptions(options);
-}
-
-string EnumDescriptor::DebugStringWithOptions(
- const DebugStringOptions& options) const {
string contents;
- DebugString(0, &contents, options);
+ DebugString(0, &contents);
return contents;
}
-void EnumDescriptor::DebugString(int depth, string *contents,
- const DebugStringOptions&
- debug_string_options) const {
+void EnumDescriptor::DebugString(int depth, string *contents) const {
string prefix(depth * 2, ' ');
++depth;
-
- SourceLocationCommentPrinter
- comment_printer(this, prefix, debug_string_options);
- comment_printer.AddPreComment(contents);
-
strings::SubstituteAndAppend(contents, "$0enum $1 {\n",
prefix, name());
FormatLineOptions(depth, options(), contents);
for (int i = 0; i < value_count(); i++) {
- value(i)->DebugString(depth, contents, debug_string_options);
+ value(i)->DebugString(depth, contents);
}
strings::SubstituteAndAppend(contents, "$0}\n", prefix);
-
- comment_printer.AddPostComment(contents);
}
string EnumValueDescriptor::DebugString() const {
- DebugStringOptions options; // default values
- return DebugStringWithOptions(options);
-}
-
-string EnumValueDescriptor::DebugStringWithOptions(
- const DebugStringOptions& options) const {
string contents;
- DebugString(0, &contents, options);
+ DebugString(0, &contents);
return contents;
}
-void EnumValueDescriptor::DebugString(int depth, string *contents,
- const DebugStringOptions&
- debug_string_options) const {
+void EnumValueDescriptor::DebugString(int depth, string *contents) const {
string prefix(depth * 2, ' ');
-
- SourceLocationCommentPrinter
- comment_printer(this, prefix, debug_string_options);
- comment_printer.AddPreComment(contents);
-
strings::SubstituteAndAppend(contents, "$0$1 = $2",
prefix, name(), number());
@@ -2432,70 +1938,39 @@ void EnumValueDescriptor::DebugString(int depth, string *contents,
strings::SubstituteAndAppend(contents, " [$0]", formatted_options);
}
contents->append(";\n");
-
- comment_printer.AddPostComment(contents);
}
string ServiceDescriptor::DebugString() const {
- DebugStringOptions options; // default values
- return DebugStringWithOptions(options);
-}
-
-string ServiceDescriptor::DebugStringWithOptions(
- const DebugStringOptions& options) const {
string contents;
- DebugString(&contents, options);
+ DebugString(&contents);
return contents;
}
-void ServiceDescriptor::DebugString(string *contents,
- const DebugStringOptions&
- debug_string_options) const {
- SourceLocationCommentPrinter
- comment_printer(this, /* prefix */ "", debug_string_options);
- comment_printer.AddPreComment(contents);
-
+void ServiceDescriptor::DebugString(string *contents) const {
strings::SubstituteAndAppend(contents, "service $0 {\n", name());
FormatLineOptions(1, options(), contents);
for (int i = 0; i < method_count(); i++) {
- method(i)->DebugString(1, contents, debug_string_options);
+ method(i)->DebugString(1, contents);
}
contents->append("}\n");
-
- comment_printer.AddPostComment(contents);
}
string MethodDescriptor::DebugString() const {
- DebugStringOptions options; // default values
- return DebugStringWithOptions(options);
-}
-
-string MethodDescriptor::DebugStringWithOptions(
- const DebugStringOptions& options) const {
string contents;
- DebugString(0, &contents, options);
+ DebugString(0, &contents);
return contents;
}
-void MethodDescriptor::DebugString(int depth, string *contents,
- const DebugStringOptions&
- debug_string_options) const {
+void MethodDescriptor::DebugString(int depth, string *contents) const {
string prefix(depth * 2, ' ');
++depth;
-
- SourceLocationCommentPrinter
- comment_printer(this, prefix, debug_string_options);
- comment_printer.AddPreComment(contents);
-
- strings::SubstituteAndAppend(contents, "$0rpc $1($4.$2) returns ($5.$3)",
+ strings::SubstituteAndAppend(contents, "$0rpc $1(.$2) returns (.$3)",
prefix, name(),
input_type()->full_name(),
- output_type()->full_name(),
- client_streaming() ? "stream " : "",
- server_streaming() ? "stream " : "");
+ output_type()->full_name());
string formatted_options;
if (FormatLineOptions(depth, options(), &formatted_options)) {
@@ -2504,31 +1979,34 @@ void MethodDescriptor::DebugString(int depth, string *contents,
} else {
contents->append(";\n");
}
-
- comment_printer.AddPostComment(contents);
}
// Location methods ===============================================
+static bool PathsEqual(const vector<int>& x, const RepeatedField<int32>& y) {
+ if (x.size() != y.size()) return false;
+ for (int i = 0; i < x.size(); ++i) {
+ if (x[i] != y.Get(i)) return false;
+ }
+ return true;
+}
+
bool FileDescriptor::GetSourceLocation(const vector<int>& path,
SourceLocation* out_location) const {
GOOGLE_CHECK_NOTNULL(out_location);
- if (source_code_info_) {
- if (const SourceCodeInfo_Location* loc =
- tables_->GetSourceLocation(path, source_code_info_)) {
- const RepeatedField<int32>& span = loc->span();
+ const SourceCodeInfo* info = source_code_info_;
+ for (int i = 0; info && i < info->location_size(); ++i) {
+ if (PathsEqual(path, info->location(i).path())) {
+ const RepeatedField<int32>& span = info->location(i).span();
if (span.size() == 3 || span.size() == 4) {
out_location->start_line = span.Get(0);
out_location->start_column = span.Get(1);
out_location->end_line = span.Get(span.size() == 3 ? 0 : 2);
out_location->end_column = span.Get(span.size() - 1);
- out_location->leading_comments = loc->leading_comments();
- out_location->trailing_comments = loc->trailing_comments();
- out_location->leading_detached_comments.assign(
- loc->leading_detached_comments().begin(),
- loc->leading_detached_comments().end());
+ out_location->leading_comments = info->location(i).leading_comments();
+ out_location->trailing_comments = info->location(i).trailing_comments();
return true;
}
}
@@ -2536,18 +2014,8 @@ bool FileDescriptor::GetSourceLocation(const vector<int>& path,
return false;
}
-bool FileDescriptor::GetSourceLocation(SourceLocation* out_location) const {
- vector<int> path; // empty path for root FileDescriptor
- return GetSourceLocation(path, out_location);
-}
-
bool FieldDescriptor::is_packed() const {
- if (!is_packable()) return false;
- if (file_->syntax() == FileDescriptor::SYNTAX_PROTO2) {
- return (options_ != NULL) && options_->packed();
- } else {
- return options_ == NULL || !options_->has_packed() || options_->packed();
- }
+ return is_packable() && (options_ != NULL) && options_->packed();
}
bool Descriptor::GetSourceLocation(SourceLocation* out_location) const {
@@ -2562,12 +2030,6 @@ bool FieldDescriptor::GetSourceLocation(SourceLocation* out_location) const {
return file()->GetSourceLocation(path, out_location);
}
-bool OneofDescriptor::GetSourceLocation(SourceLocation* out_location) const {
- vector<int> path;
- GetLocationPath(&path);
- return containing_type()->file()->GetSourceLocation(path, out_location);
-}
-
bool EnumDescriptor::GetSourceLocation(SourceLocation* out_location) const {
vector<int> path;
GetLocationPath(&path);
@@ -2605,25 +2067,8 @@ void Descriptor::GetLocationPath(vector<int>* output) const {
}
void FieldDescriptor::GetLocationPath(vector<int>* output) const {
- if (is_extension()) {
- if (extension_scope() == NULL) {
- output->push_back(FileDescriptorProto::kExtensionFieldNumber);
- output->push_back(index());
- } else {
- extension_scope()->GetLocationPath(output);
- output->push_back(DescriptorProto::kExtensionFieldNumber);
- output->push_back(index());
- }
- } else {
- containing_type()->GetLocationPath(output);
- output->push_back(DescriptorProto::kFieldFieldNumber);
- output->push_back(index());
- }
-}
-
-void OneofDescriptor::GetLocationPath(vector<int>* output) const {
containing_type()->GetLocationPath(output);
- output->push_back(DescriptorProto::kOneofDeclFieldNumber);
+ output->push_back(DescriptorProto::kFieldFieldNumber);
output->push_back(index());
}
@@ -2660,7 +2105,7 @@ void MethodDescriptor::GetLocationPath(vector<int>* output) const {
namespace {
// Represents an options message to interpret. Extension names in the option
-// name are resolved relative to name_scope. element_name and orig_opt are
+// name are respolved relative to name_scope. element_name and orig_opt are
// used only for error reporting (since the parser records locations against
// pointers in the original options, not the mutable copy). The Message must be
// one of the Options messages in descriptor.proto.
@@ -2709,10 +2154,6 @@ class DescriptorBuilder {
FileDescriptorTables* file_tables_;
set<const FileDescriptor*> dependencies_;
- // unused_dependency_ is used to record the unused imported files.
- // Note: public import is not considered.
- set<const FileDescriptor*> unused_dependency_;
-
// If LookupSymbol() finds a symbol that is in a file which is not a declared
// dependency of this file, it will fail, but will set
// possible_undeclared_dependency_ to point at that file. This is only used
@@ -2723,22 +2164,10 @@ class DescriptorBuilder {
const FileDescriptor* possible_undeclared_dependency_;
string possible_undeclared_dependency_name_;
- // If LookupSymbol() could resolve a symbol which is not defined,
- // record the resolved name. This is only used by AddNotDefinedError()
- // to report a more useful error message.
- string undefine_resolved_name_;
-
void AddError(const string& element_name,
const Message& descriptor,
DescriptorPool::ErrorCollector::ErrorLocation location,
const string& error);
- void AddError(const string& element_name,
- const Message& descriptor,
- DescriptorPool::ErrorCollector::ErrorLocation location,
- const char* error);
- void AddRecursiveImportError(const FileDescriptorProto& proto, int from_here);
- void AddTwiceListedError(const FileDescriptorProto& proto, int index);
- void AddImportError(const FileDescriptorProto& proto, int index);
// Adds an error indicating that undefined_symbol was not defined. Must
// only be called after LookupSymbol() fails.
@@ -2748,10 +2177,6 @@ class DescriptorBuilder {
DescriptorPool::ErrorCollector::ErrorLocation location,
const string& undefined_symbol);
- void AddWarning(const string& element_name, const Message& descriptor,
- DescriptorPool::ErrorCollector::ErrorLocation location,
- const string& error);
-
// Silly helper which determines if the given file is in the given package.
// I.e., either file->package() == package_name or file->package() is a
// nested package within package_name.
@@ -2813,7 +2238,7 @@ class DescriptorBuilder {
// Creates a placeholder file. Never returns NULL. This is used when an
// import is not found and AllowUnknownDependencies() is enabled.
- FileDescriptor* NewPlaceholderFile(const string& name);
+ const FileDescriptor* NewPlaceholderFile(const string& name);
// Calls tables_->AddSymbol() and records an error if it fails. Returns
// true if successful or false if failed, though most callers can ignore
@@ -2886,12 +2311,6 @@ class DescriptorBuilder {
void BuildExtensionRange(const DescriptorProto::ExtensionRange& proto,
const Descriptor* parent,
Descriptor::ExtensionRange* result);
- void BuildReservedRange(const DescriptorProto::ReservedRange& proto,
- const Descriptor* parent,
- Descriptor::ReservedRange* result);
- void BuildOneof(const OneofDescriptorProto& proto,
- Descriptor* parent,
- OneofDescriptor* result);
void BuildEnum(const EnumDescriptorProto& proto,
const Descriptor* parent,
EnumDescriptor* result);
@@ -2905,8 +2324,6 @@ class DescriptorBuilder {
const ServiceDescriptor* parent,
MethodDescriptor* result);
- void LogUnusedDependency(const FileDescriptor* result);
-
// Must be run only after building.
//
// NOTE: Options will not be available during cross-linking, as they
@@ -3042,9 +2459,6 @@ class DescriptorBuilder {
static inline bool get_allow_unknown(const DescriptorPool* pool) {
return pool->allow_unknown_;
}
- static inline bool get_enforce_weak(const DescriptorPool* pool) {
- return pool->enforce_weak_;
- }
static inline bool get_is_placeholder(const Descriptor* descriptor) {
return descriptor->is_placeholder_;
}
@@ -3074,24 +2488,9 @@ class DescriptorBuilder {
const ServiceDescriptorProto& proto);
void ValidateMethodOptions(MethodDescriptor* method,
const MethodDescriptorProto& proto);
- void ValidateProto3(FileDescriptor* file,
- const FileDescriptorProto& proto);
- void ValidateProto3Message(Descriptor* message,
- const DescriptorProto& proto);
- void ValidateProto3Field(FieldDescriptor* field,
- const FieldDescriptorProto& proto);
- void ValidateProto3Enum(EnumDescriptor* enm,
- const EnumDescriptorProto& proto);
-
- // Returns true if the map entry message is compatible with the
- // auto-generated entry message from map fields syntax.
- bool ValidateMapEntry(FieldDescriptor* field,
- const FieldDescriptorProto& proto);
-
- // Recursively detects naming conflicts with map entry types for a
- // better error message.
- void DetectMapConflicts(const Descriptor* message,
- const DescriptorProto& proto);
+
+ void ValidateMapKey(FieldDescriptor* field,
+ const FieldDescriptorProto& proto);
};
@@ -3102,8 +2501,6 @@ const FileDescriptor* DescriptorPool::BuildFile(
"DescriptorDatabase. You must instead find a way to get your file "
"into the underlying database.";
GOOGLE_CHECK(mutex_ == NULL); // Implied by the above GOOGLE_CHECK.
- tables_->known_bad_symbols_.clear();
- tables_->known_bad_files_.clear();
return DescriptorBuilder(this, tables_.get(), NULL).BuildFile(proto);
}
@@ -3115,8 +2512,6 @@ const FileDescriptor* DescriptorPool::BuildFileCollectingErrors(
"DescriptorDatabase. You must instead find a way to get your file "
"into the underlying database.";
GOOGLE_CHECK(mutex_ == NULL); // Implied by the above GOOGLE_CHECK.
- tables_->known_bad_symbols_.clear();
- tables_->known_bad_files_.clear();
return DescriptorBuilder(this, tables_.get(),
error_collector).BuildFile(proto);
}
@@ -3124,16 +2519,8 @@ const FileDescriptor* DescriptorPool::BuildFileCollectingErrors(
const FileDescriptor* DescriptorPool::BuildFileFromDatabase(
const FileDescriptorProto& proto) const {
mutex_->AssertHeld();
- if (tables_->known_bad_files_.count(proto.name()) > 0) {
- return NULL;
- }
- const FileDescriptor* result =
- DescriptorBuilder(this, tables_.get(),
- default_error_collector_).BuildFile(proto);
- if (result == NULL) {
- tables_->known_bad_files_.insert(proto.name());
- }
- return result;
+ return DescriptorBuilder(this, tables_.get(),
+ default_error_collector_).BuildFile(proto);
}
DescriptorBuilder::DescriptorBuilder(
@@ -3144,8 +2531,7 @@ DescriptorBuilder::DescriptorBuilder(
tables_(tables),
error_collector_(error_collector),
had_errors_(false),
- possible_undeclared_dependency_(NULL),
- undefine_resolved_name_("") {}
+ possible_undeclared_dependency_(NULL) {}
DescriptorBuilder::~DescriptorBuilder() {}
@@ -3167,53 +2553,21 @@ void DescriptorBuilder::AddError(
had_errors_ = true;
}
-void DescriptorBuilder::AddError(
- const string& element_name,
- const Message& descriptor,
- DescriptorPool::ErrorCollector::ErrorLocation location,
- const char* error) {
- AddError(element_name, descriptor, location, string(error));
-}
-
void DescriptorBuilder::AddNotDefinedError(
const string& element_name,
const Message& descriptor,
DescriptorPool::ErrorCollector::ErrorLocation location,
const string& undefined_symbol) {
- if (possible_undeclared_dependency_ == NULL &&
- undefine_resolved_name_.empty()) {
+ if (possible_undeclared_dependency_ == NULL) {
AddError(element_name, descriptor, location,
"\"" + undefined_symbol + "\" is not defined.");
} else {
- if (possible_undeclared_dependency_ != NULL) {
- AddError(element_name, descriptor, location,
- "\"" + possible_undeclared_dependency_name_ +
- "\" seems to be defined in \"" +
- possible_undeclared_dependency_->name() + "\", which is not "
- "imported by \"" + filename_ + "\". To use it here, please "
- "add the necessary import.");
- }
- if (!undefine_resolved_name_.empty()) {
- AddError(element_name, descriptor, location,
- "\"" + undefined_symbol + "\" is resolved to \"" +
- undefine_resolved_name_ + "\", which is not defined. "
- "The innermost scope is searched first in name resolution. "
- "Consider using a leading '.'(i.e., \"."
- + undefined_symbol +
- "\") to start from the outermost scope.");
- }
- }
-}
-
-void DescriptorBuilder::AddWarning(
- const string& element_name, const Message& descriptor,
- DescriptorPool::ErrorCollector::ErrorLocation location,
- const string& error) {
- if (error_collector_ == NULL) {
- GOOGLE_LOG(WARNING) << filename_ << " " << element_name << ": " << error;
- } else {
- error_collector_->AddWarning(filename_, element_name, &descriptor, location,
- error);
+ AddError(element_name, descriptor, location,
+ "\"" + possible_undeclared_dependency_name_ +
+ "\" seems to be defined in \"" +
+ possible_undeclared_dependency_->name() + "\", which is not "
+ "imported by \"" + filename_ + "\". To use it here, please "
+ "add the necessary import.");
}
}
@@ -3274,10 +2628,7 @@ Symbol DescriptorBuilder::FindSymbol(const string& name) {
// Only find symbols which were defined in this file or one of its
// dependencies.
const FileDescriptor* file = result.GetFile();
- if (file == file_ || dependencies_.count(file) > 0) {
- unused_dependency_.erase(file);
- return result;
- }
+ if (file == file_ || dependencies_.count(file) > 0) return result;
if (result.type == Symbol::PACKAGE) {
// Arg, this is overcomplicated. The symbol is a package name. It could
@@ -3303,7 +2654,6 @@ Symbol DescriptorBuilder::FindSymbol(const string& name) {
Symbol DescriptorBuilder::LookupSymbolNoPlaceholder(
const string& name, const string& relative_to, ResolveMode resolve_mode) {
possible_undeclared_dependency_ = NULL;
- undefine_resolved_name_.clear();
if (name.size() > 0 && name[0] == '.') {
// Fully-qualified name.
@@ -3352,11 +2702,7 @@ Symbol DescriptorBuilder::LookupSymbolNoPlaceholder(
if (result.IsAggregate()) {
scope_to_try.append(name, first_part_of_name.size(),
name.size() - first_part_of_name.size());
- result = FindSymbol(scope_to_try);
- if (result.IsNull()) {
- undefine_resolved_name_ = scope_to_try;
- }
- return result;
+ return FindSymbol(scope_to_try);
} else {
// We found a symbol but it's not an aggregate. Continue the loop.
}
@@ -3409,14 +2755,23 @@ Symbol DescriptorBuilder::NewPlaceholder(const string& name,
placeholder_name = tables_->AllocateString(
placeholder_full_name->substr(dotpos + 1));
} else {
- placeholder_package = &internal::GetEmptyString();
+ placeholder_package = &::google::protobuf::internal::GetEmptyString();
placeholder_name = placeholder_full_name;
}
// Create the placeholders.
- FileDescriptor* placeholder_file = NewPlaceholderFile(
- *placeholder_full_name + ".placeholder.proto");
+ FileDescriptor* placeholder_file = tables_->Allocate<FileDescriptor>();
+ memset(placeholder_file, 0, sizeof(*placeholder_file));
+
+ placeholder_file->source_code_info_ = &SourceCodeInfo::default_instance();
+
+ placeholder_file->name_ =
+ tables_->AllocateString(*placeholder_full_name + ".placeholder.proto");
placeholder_file->package_ = placeholder_package;
+ placeholder_file->pool_ = pool_;
+ placeholder_file->options_ = &FileOptions::default_instance();
+ placeholder_file->tables_ = &FileDescriptorTables::kEmpty;
+ // All other fields are zero or NULL.
if (placeholder_type == PLACEHOLDER_ENUM) {
placeholder_file->enum_type_count_ = 1;
@@ -3480,19 +2835,16 @@ Symbol DescriptorBuilder::NewPlaceholder(const string& name,
}
}
-FileDescriptor* DescriptorBuilder::NewPlaceholderFile(
+const FileDescriptor* DescriptorBuilder::NewPlaceholderFile(
const string& name) {
FileDescriptor* placeholder = tables_->Allocate<FileDescriptor>();
memset(placeholder, 0, sizeof(*placeholder));
placeholder->name_ = tables_->AllocateString(name);
- placeholder->package_ = &internal::GetEmptyString();
+ placeholder->package_ = &::google::protobuf::internal::GetEmptyString();
placeholder->pool_ = pool_;
placeholder->options_ = &FileOptions::default_instance();
placeholder->tables_ = &FileDescriptorTables::kEmpty;
- placeholder->source_code_info_ = &SourceCodeInfo::default_instance();
- placeholder->is_placeholder_ = true;
- placeholder->syntax_ = FileDescriptor::SYNTAX_PROTO2;
// All other fields are zero or NULL.
return placeholder;
@@ -3663,45 +3015,6 @@ template<class DescriptorT> void DescriptorBuilder::AllocateOptionsImpl(
METHOD(INPUT.NAME(i), PARENT, OUTPUT->NAME##s_ + i); \
}
-void DescriptorBuilder::AddRecursiveImportError(
- const FileDescriptorProto& proto, int from_here) {
- string error_message("File recursively imports itself: ");
- for (int i = from_here; i < tables_->pending_files_.size(); i++) {
- error_message.append(tables_->pending_files_[i]);
- error_message.append(" -> ");
- }
- error_message.append(proto.name());
-
- AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER,
- error_message);
-}
-
-void DescriptorBuilder::AddTwiceListedError(const FileDescriptorProto& proto,
- int index) {
- AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER,
- "Import \"" + proto.dependency(index) + "\" was listed twice.");
-}
-
-void DescriptorBuilder::AddImportError(const FileDescriptorProto& proto,
- int index) {
- string message;
- if (pool_->fallback_database_ == NULL) {
- message = "Import \"" + proto.dependency(index) +
- "\" has not been loaded.";
- } else {
- message = "Import \"" + proto.dependency(index) +
- "\" was not found or had errors.";
- }
- AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, message);
-}
-
-static bool ExistingFileMatchesProto(const FileDescriptor* existing_file,
- const FileDescriptorProto& proto) {
- FileDescriptorProto existing_proto;
- existing_file->CopyTo(&existing_proto);
- return existing_proto.SerializeAsString() == proto.SerializeAsString();
-}
-
const FileDescriptor* DescriptorBuilder::BuildFile(
const FileDescriptorProto& proto) {
filename_ = proto.name();
@@ -3710,11 +3023,13 @@ const FileDescriptor* DescriptorBuilder::BuildFile(
// Note: This only works if the input is canonical -- that is, it
// fully-qualifies all type names, has no UninterpretedOptions, etc.
// This is fine, because this idempotency "feature" really only exists to
- // accommodate one hack in the proto1->proto2 migration layer.
+ // accomodate one hack in the proto1->proto2 migration layer.
const FileDescriptor* existing_file = tables_->FindFile(filename_);
if (existing_file != NULL) {
// File already in pool. Compare the existing one to the input.
- if (ExistingFileMatchesProto(existing_file, proto)) {
+ FileDescriptorProto existing_proto;
+ existing_file->CopyTo(&existing_proto);
+ if (existing_proto.SerializeAsString() == proto.SerializeAsString()) {
// They're identical. Return the existing descriptor.
return existing_file;
}
@@ -3733,7 +3048,15 @@ const FileDescriptor* DescriptorBuilder::BuildFile(
// at all.
for (int i = 0; i < tables_->pending_files_.size(); i++) {
if (tables_->pending_files_[i] == proto.name()) {
- AddRecursiveImportError(proto, i);
+ string error_message("File recursively imports itself: ");
+ for (; i < tables_->pending_files_.size(); i++) {
+ error_message.append(tables_->pending_files_[i]);
+ error_message.append(" -> ");
+ }
+ error_message.append(proto.name());
+
+ AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER,
+ error_message);
return NULL;
}
}
@@ -3760,7 +3083,6 @@ const FileDescriptor* DescriptorBuilder::BuildFile(
FileDescriptor* result = tables_->Allocate<FileDescriptor>();
file_ = result;
- result->is_placeholder_ = false;
if (proto.has_source_code_info()) {
SourceCodeInfo *info = tables_->AllocateMessage<SourceCodeInfo>();
info->CopyFrom(proto.source_code_info());
@@ -3777,18 +3099,6 @@ const FileDescriptor* DescriptorBuilder::BuildFile(
"Missing field: FileDescriptorProto.name.");
}
- // TODO(liujisi): Report error when the syntax is empty after all the protos
- // have added the syntax statement.
- if (proto.syntax().empty() || proto.syntax() == "proto2") {
- file_->syntax_ = FileDescriptor::SYNTAX_PROTO2;
- } else if (proto.syntax() == "proto3") {
- file_->syntax_ = FileDescriptor::SYNTAX_PROTO3;
- } else {
- file_->syntax_ = FileDescriptor::SYNTAX_UNKNOWN;
- AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER,
- "Unrecognized syntax: " + proto.syntax());
- }
-
result->name_ = tables_->AllocateString(proto.name());
if (proto.has_package()) {
result->package_ = tables_->AllocateString(proto.package());
@@ -3819,14 +3129,11 @@ const FileDescriptor* DescriptorBuilder::BuildFile(
result->dependency_count_ = proto.dependency_size();
result->dependencies_ =
tables_->AllocateArray<const FileDescriptor*>(proto.dependency_size());
- unused_dependency_.clear();
- set<int> weak_deps;
- for (int i = 0; i < proto.weak_dependency_size(); ++i) {
- weak_deps.insert(proto.weak_dependency(i));
- }
for (int i = 0; i < proto.dependency_size(); i++) {
if (!seen_dependencies.insert(proto.dependency(i)).second) {
- AddTwiceListedError(proto, i);
+ AddError(proto.name(), proto,
+ DescriptorPool::ErrorCollector::OTHER,
+ "Import \"" + proto.dependency(i) + "\" was listed twice.");
}
const FileDescriptor* dependency = tables_->FindFile(proto.dependency(i));
@@ -3835,20 +3142,20 @@ const FileDescriptor* DescriptorBuilder::BuildFile(
}
if (dependency == NULL) {
- if (pool_->allow_unknown_ ||
- (!pool_->enforce_weak_ && weak_deps.find(i) != weak_deps.end())) {
+ if (pool_->allow_unknown_) {
dependency = NewPlaceholderFile(proto.dependency(i));
} else {
- AddImportError(proto, i);
- }
- } else {
- // Add to unused_dependency_ to track unused imported files.
- // Note: do not track unused imported files for public import.
- if (pool_->enforce_dependencies_ &&
- (pool_->unused_import_track_files_.find(proto.name()) !=
- pool_->unused_import_track_files_.end()) &&
- (dependency->public_dependency_count() == 0)) {
- unused_dependency_.insert(dependency);
+ string message;
+ if (pool_->fallback_database_ == NULL) {
+ message = "Import \"" + proto.dependency(i) +
+ "\" has not been loaded.";
+ } else {
+ message = "Import \"" + proto.dependency(i) +
+ "\" was not found or had errors.";
+ }
+ AddError(proto.name(), proto,
+ DescriptorPool::ErrorCollector::OTHER,
+ message);
}
}
@@ -3864,8 +3171,6 @@ const FileDescriptor* DescriptorBuilder::BuildFile(
int index = proto.public_dependency(i);
if (index >= 0 && index < proto.dependency_size()) {
result->public_dependencies_[public_dependency_count++] = index;
- // Do not track unused imported files for public import.
- unused_dependency_.erase(result->dependency(index));
} else {
AddError(proto.name(), proto,
DescriptorPool::ErrorCollector::OTHER,
@@ -3932,19 +3237,6 @@ const FileDescriptor* DescriptorBuilder::BuildFile(
ValidateFileOptions(result, proto);
}
- // Additional naming conflict check for map entry types. Only need to check
- // this if there are already errors.
- if (had_errors_) {
- for (int i = 0; i < proto.message_type_size(); ++i) {
- DetectMapConflicts(result->message_type(i), proto.message_type(i));
- }
- }
-
-
- if (!unused_dependency_.empty()) {
- LogUnusedDependency(result);
- }
-
if (had_errors_) {
tables_->RollbackToLastCheckpoint();
return NULL;
@@ -3972,24 +3264,11 @@ void DescriptorBuilder::BuildMessage(const DescriptorProto& proto,
result->is_placeholder_ = false;
result->is_unqualified_placeholder_ = false;
- // Build oneofs first so that fields and extension ranges can refer to them.
- BUILD_ARRAY(proto, result, oneof_decl , BuildOneof , result);
BUILD_ARRAY(proto, result, field , BuildField , result);
BUILD_ARRAY(proto, result, nested_type , BuildMessage , result);
BUILD_ARRAY(proto, result, enum_type , BuildEnum , result);
BUILD_ARRAY(proto, result, extension_range, BuildExtensionRange, result);
BUILD_ARRAY(proto, result, extension , BuildExtension , result);
- BUILD_ARRAY(proto, result, reserved_range , BuildReservedRange , result);
-
- // Copy reserved names.
- int reserved_name_count = proto.reserved_name_size();
- result->reserved_name_count_ = reserved_name_count;
- result->reserved_names_ =
- tables_->AllocateArray<const string*>(reserved_name_count);
- for (int i = 0; i < reserved_name_count; ++i) {
- result->reserved_names_[i] =
- tables_->AllocateString(proto.reserved_name(i));
- }
// Copy options.
if (!proto.has_options()) {
@@ -4001,34 +3280,7 @@ void DescriptorBuilder::BuildMessage(const DescriptorProto& proto,
AddSymbol(result->full_name(), parent, result->name(),
proto, Symbol(result));
- for (int i = 0; i < proto.reserved_range_size(); i++) {
- const DescriptorProto_ReservedRange& range1 = proto.reserved_range(i);
- for (int j = i + 1; j < proto.reserved_range_size(); j++) {
- const DescriptorProto_ReservedRange& range2 = proto.reserved_range(j);
- if (range1.end() > range2.start() && range2.end() > range1.start()) {
- AddError(result->full_name(), proto.reserved_range(i),
- DescriptorPool::ErrorCollector::NUMBER,
- strings::Substitute("Reserved range $0 to $1 overlaps with "
- "already-defined range $2 to $3.",
- range2.start(), range2.end() - 1,
- range1.start(), range1.end() - 1));
- }
- }
- }
-
- hash_set<string> reserved_name_set;
- for (int i = 0; i < proto.reserved_name_size(); i++) {
- const string& name = proto.reserved_name(i);
- if (reserved_name_set.find(name) == reserved_name_set.end()) {
- reserved_name_set.insert(name);
- } else {
- AddError(name, proto, DescriptorPool::ErrorCollector::NAME,
- strings::Substitute(
- "Field name \"$0\" is reserved multiple times.",
- name));
- }
- }
-
+ // Check that no fields have numbers in extension ranges.
for (int i = 0; i < result->field_count(); i++) {
const FieldDescriptor* field = result->field(i);
for (int j = 0; j < result->extension_range_count(); j++) {
@@ -4042,39 +3294,11 @@ void DescriptorBuilder::BuildMessage(const DescriptorProto& proto,
field->name(), field->number()));
}
}
- for (int j = 0; j < result->reserved_range_count(); j++) {
- const Descriptor::ReservedRange* range = result->reserved_range(j);
- if (range->start <= field->number() && field->number() < range->end) {
- AddError(field->full_name(), proto.reserved_range(j),
- DescriptorPool::ErrorCollector::NUMBER,
- strings::Substitute(
- "Field \"$0\" uses reserved number $1.",
- field->name(), field->number()));
- }
- }
- if (reserved_name_set.find(field->name()) != reserved_name_set.end()) {
- AddError(field->full_name(), proto.field(i),
- DescriptorPool::ErrorCollector::NAME,
- strings::Substitute(
- "Field name \"$0\" is reserved.", field->name()));
- }
}
- // Check that extension ranges don't overlap and don't include
- // reserved field numbers.
+ // Check that extension ranges don't overlap.
for (int i = 0; i < result->extension_range_count(); i++) {
const Descriptor::ExtensionRange* range1 = result->extension_range(i);
- for (int j = 0; j < result->reserved_range_count(); j++) {
- const Descriptor::ReservedRange* range2 = result->reserved_range(j);
- if (range1->end > range2->start && range2->end > range1->start) {
- AddError(result->full_name(), proto.extension_range(j),
- DescriptorPool::ErrorCollector::NUMBER,
- strings::Substitute("Extension range $0 to $1 overlaps with "
- "reserved range $2 to $3.",
- range1->start, range1->end - 1,
- range2->start, range2->end - 1));
- }
- }
for (int j = i + 1; j < result->extension_range_count(); j++) {
const Descriptor::ExtensionRange* range2 = result->extension_range(j);
if (range1->end > range2->start && range2->end > range1->start) {
@@ -4121,9 +3345,7 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
// Don't bother with the above optimization for camel-case names since
// .proto files that follow the guide shouldn't be using names in this
// format, so the optimization wouldn't help much.
- result->camelcase_name_ =
- tables_->AllocateString(ToCamelCase(proto.name(),
- /* lower_first = */ true));
+ result->camelcase_name_ = tables_->AllocateString(ToCamelCase(proto.name()));
// Some compilers do not allow static_cast directly between two enum types,
// so we must cast to int first.
@@ -4132,22 +3354,10 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
result->label_ = static_cast<FieldDescriptor::Label>(
implicit_cast<int>(proto.label()));
- // An extension cannot have a required field (b/13365836).
- if (result->is_extension_ &&
- result->label_ == FieldDescriptor::LABEL_REQUIRED) {
- AddError(result->full_name(), proto,
- // Error location `TYPE`: we would really like to indicate
- // `LABEL`, but the `ErrorLocation` enum has no entry for this, and
- // we don't necessarily know about all implementations of the
- // `ErrorCollector` interface to extend them to handle the new
- // error location type properly.
- DescriptorPool::ErrorCollector::TYPE,
- "Message extensions cannot have required fields.");
- }
-
// Some of these may be filled in when cross-linking.
result->containing_type_ = NULL;
result->extension_scope_ = NULL;
+ result->experimental_map_key_ = NULL;
result->message_type_ = NULL;
result->enum_type_ = NULL;
@@ -4187,7 +3397,7 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
result->default_value_float_ = numeric_limits<float>::quiet_NaN();
} else {
result->default_value_float_ =
- io::NoLocaleStrtod(proto.default_value().c_str(), &end_pos);
+ NoLocaleStrtod(proto.default_value().c_str(), &end_pos);
}
break;
case FieldDescriptor::CPPTYPE_DOUBLE:
@@ -4199,7 +3409,7 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
result->default_value_double_ = numeric_limits<double>::quiet_NaN();
} else {
result->default_value_double_ =
- io::NoLocaleStrtod(proto.default_value().c_str(), &end_pos);
+ NoLocaleStrtod(proto.default_value().c_str(), &end_pos);
}
break;
case FieldDescriptor::CPPTYPE_BOOL:
@@ -4241,8 +3451,7 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
if (proto.default_value().empty() || *end_pos != '\0') {
AddError(result->full_name(), proto,
DescriptorPool::ErrorCollector::DEFAULT_VALUE,
- "Couldn't parse default value \"" + proto.default_value() +
- "\".");
+ "Couldn't parse default value.");
}
}
} else {
@@ -4274,7 +3483,7 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
result->default_value_enum_ = NULL;
break;
case FieldDescriptor::CPPTYPE_STRING:
- result->default_value_string_ = &internal::GetEmptyString();
+ result->default_value_string_ = &::google::protobuf::internal::GetEmptyString();
break;
case FieldDescriptor::CPPTYPE_MESSAGE:
break;
@@ -4315,16 +3524,6 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
}
result->extension_scope_ = parent;
-
- if (proto.has_oneof_index()) {
- AddError(result->full_name(), proto,
- DescriptorPool::ErrorCollector::OTHER,
- "FieldDescriptorProto.oneof_index should not be set for "
- "extensions.");
- }
-
- // Fill in later (maybe).
- result->containing_oneof_ = NULL;
} else {
if (proto.has_extendee()) {
AddError(result->full_name(), proto,
@@ -4333,23 +3532,6 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
}
result->containing_type_ = parent;
-
- if (proto.has_oneof_index()) {
- if (proto.oneof_index() < 0 ||
- proto.oneof_index() >= parent->oneof_decl_count()) {
- AddError(result->full_name(), proto,
- DescriptorPool::ErrorCollector::OTHER,
- strings::Substitute("FieldDescriptorProto.oneof_index $0 is "
- "out of range for type \"$1\".",
- proto.oneof_index(),
- parent->name()));
- result->containing_oneof_ = NULL;
- } else {
- result->containing_oneof_ = parent->oneof_decl(proto.oneof_index());
- }
- } else {
- result->containing_oneof_ = NULL;
- }
}
// Copy options.
@@ -4387,41 +3569,6 @@ void DescriptorBuilder::BuildExtensionRange(
}
}
-void DescriptorBuilder::BuildReservedRange(
- const DescriptorProto::ReservedRange& proto,
- const Descriptor* parent,
- Descriptor::ReservedRange* result) {
- result->start = proto.start();
- result->end = proto.end();
- if (result->start <= 0) {
- AddError(parent->full_name(), proto,
- DescriptorPool::ErrorCollector::NUMBER,
- "Reserved numbers must be positive integers.");
- }
-}
-
-void DescriptorBuilder::BuildOneof(const OneofDescriptorProto& proto,
- Descriptor* parent,
- OneofDescriptor* result) {
- string* full_name = tables_->AllocateString(parent->full_name());
- full_name->append(1, '.');
- full_name->append(proto.name());
-
- ValidateSymbolName(proto.name(), *full_name, proto);
-
- result->name_ = tables_->AllocateString(proto.name());
- result->full_name_ = full_name;
-
- result->containing_type_ = parent;
-
- // We need to fill these in later.
- result->field_count_ = 0;
- result->fields_ = NULL;
-
- AddSymbol(result->full_name(), parent, result->name(),
- proto, Symbol(result));
-}
-
void DescriptorBuilder::BuildEnum(const EnumDescriptorProto& proto,
const Descriptor* parent,
EnumDescriptor* result) {
@@ -4530,7 +3677,7 @@ void DescriptorBuilder::BuildEnumValue(const EnumValueDescriptorProto& proto,
}
void DescriptorBuilder::BuildService(const ServiceDescriptorProto& proto,
- const void* /* dummy */,
+ const void* dummy,
ServiceDescriptor* result) {
string* full_name = tables_->AllocateString(file_->package());
if (!full_name->empty()) full_name->append(1, '.');
@@ -4579,9 +3726,6 @@ void DescriptorBuilder::BuildMethod(const MethodDescriptorProto& proto,
AllocateOptions(proto.options(), result);
}
- result->client_streaming_ = proto.client_streaming();
- result->server_streaming_ = proto.server_streaming();
-
AddSymbol(result->full_name(), parent, result->name(),
proto, Symbol(result));
}
@@ -4634,63 +3778,6 @@ void DescriptorBuilder::CrossLinkMessage(
for (int i = 0; i < message->extension_count(); i++) {
CrossLinkField(&message->extensions_[i], proto.extension(i));
}
-
- // Set up field array for each oneof.
-
- // First count the number of fields per oneof.
- for (int i = 0; i < message->field_count(); i++) {
- const OneofDescriptor* oneof_decl = message->field(i)->containing_oneof();
- if (oneof_decl != NULL) {
- // Make sure fields belonging to the same oneof are defined consecutively.
- // This enables optimizations in codegens and reflection libraries to
- // skip fields in the oneof group, as only one of the field can be set.
- // Note that field_count() returns how many fields in this oneof we have
- // seen so far. field_count() > 0 guarantees that i > 0, so field(i-1) is
- // safe.
- if (oneof_decl->field_count() > 0 &&
- message->field(i - 1)->containing_oneof() != oneof_decl) {
- AddWarning(
- message->full_name() + "." + message->field(i - 1)->name(),
- proto.field(i - 1), DescriptorPool::ErrorCollector::OTHER,
- strings::Substitute(
- "Fields in the same oneof must be defined consecutively. "
- "\"$0\" cannot be defined before the completion of the "
- "\"$1\" oneof definition.",
- message->field(i - 1)->name(), oneof_decl->name()));
- }
- // Must go through oneof_decls_ array to get a non-const version of the
- // OneofDescriptor.
- ++message->oneof_decls_[oneof_decl->index()].field_count_;
- }
- }
-
- // Then allocate the arrays.
- for (int i = 0; i < message->oneof_decl_count(); i++) {
- OneofDescriptor* oneof_decl = &message->oneof_decls_[i];
-
- if (oneof_decl->field_count() == 0) {
- AddError(message->full_name() + "." + oneof_decl->name(),
- proto.oneof_decl(i),
- DescriptorPool::ErrorCollector::NAME,
- "Oneof must have at least one field.");
- }
-
- oneof_decl->fields_ =
- tables_->AllocateArray<const FieldDescriptor*>(oneof_decl->field_count_);
- oneof_decl->field_count_ = 0;
- }
-
- // Then fill them in.
- for (int i = 0; i < message->field_count(); i++) {
- const OneofDescriptor* oneof_decl = message->field(i)->containing_oneof();
- if (oneof_decl != NULL) {
- OneofDescriptor* mutable_oneof_decl =
- &message->oneof_decls_[oneof_decl->index()];
- message->fields_[i].index_in_oneof_ = mutable_oneof_decl->field_count_;
- mutable_oneof_decl->fields_[mutable_oneof_decl->field_count_++] =
- message->field(i);
- }
- }
}
void DescriptorBuilder::CrossLinkField(
@@ -4715,10 +3802,7 @@ void DescriptorBuilder::CrossLinkField(
}
field->containing_type_ = extendee.descriptor;
- const Descriptor::ExtensionRange* extension_range = field->containing_type()
- ->FindExtensionRangeContainingNumber(field->number());
-
- if (extension_range == NULL) {
+ if (!field->containing_type()->IsExtensionNumber(field->number())) {
AddError(field->full_name(), proto,
DescriptorPool::ErrorCollector::NUMBER,
strings::Substitute("\"$0\" does not declare $1 as an "
@@ -4728,17 +3812,6 @@ void DescriptorBuilder::CrossLinkField(
}
}
- if (field->containing_oneof() != NULL) {
- if (field->label() != FieldDescriptor::LABEL_OPTIONAL) {
- // Note that this error will never happen when parsing .proto files.
- // It can only happen if you manually construct a FileDescriptorProto
- // that is incorrect.
- AddError(field->full_name(), proto,
- DescriptorPool::ErrorCollector::NAME,
- "Fields of oneofs must themselves have label LABEL_OPTIONAL.");
- }
- }
-
if (proto.has_type_name()) {
// Assume we are expecting a message type unless the proto contains some
// evidence that it expects an enum type. This only makes a difference if
@@ -4751,11 +3824,6 @@ void DescriptorBuilder::CrossLinkField(
expecting_enum ? PLACEHOLDER_ENUM : PLACEHOLDER_MESSAGE,
LOOKUP_TYPES);
- // If the type is a weak type, we change the type to a google.protobuf.Empty field.
- if (type.IsNull() && !pool_->enforce_weak_ && proto.options().weak()) {
- type = FindSymbol(kNonLinkedWeakMessageReplacementName);
- }
-
if (type.IsNull()) {
AddNotDefinedError(field->full_name(), proto,
DescriptorPool::ErrorCollector::TYPE,
@@ -4807,34 +3875,21 @@ void DescriptorBuilder::CrossLinkField(
}
if (field->has_default_value()) {
- // Ensure that the default value is an identifier. Parser cannot always
- // verify this because it does not have complete type information.
- // N.B. that this check yields better error messages but is not
- // necessary for correctness (an enum symbol must be a valid identifier
- // anyway), only for better errors.
- if (!io::Tokenizer::IsIdentifier(proto.default_value())) {
+ // We can't just use field->enum_type()->FindValueByName() here
+ // because that locks the pool's mutex, which we have already locked
+ // at this point.
+ Symbol default_value =
+ LookupSymbolNoPlaceholder(proto.default_value(),
+ field->enum_type()->full_name());
+
+ if (default_value.type == Symbol::ENUM_VALUE &&
+ default_value.enum_value_descriptor->type() == field->enum_type()) {
+ field->default_value_enum_ = default_value.enum_value_descriptor;
+ } else {
AddError(field->full_name(), proto,
DescriptorPool::ErrorCollector::DEFAULT_VALUE,
- "Default value for an enum field must be an identifier.");
- } else {
- // We can't just use field->enum_type()->FindValueByName() here
- // because that locks the pool's mutex, which we have already locked
- // at this point.
- Symbol default_value =
- LookupSymbolNoPlaceholder(proto.default_value(),
- field->enum_type()->full_name());
-
- if (default_value.type == Symbol::ENUM_VALUE &&
- default_value.enum_value_descriptor->type() ==
- field->enum_type()) {
- field->default_value_enum_ = default_value.enum_value_descriptor;
- } else {
- AddError(field->full_name(), proto,
- DescriptorPool::ErrorCollector::DEFAULT_VALUE,
- "Enum type \"" + field->enum_type()->full_name() +
- "\" has no value named \"" + proto.default_value() +
- "\".");
- }
+ "Enum type \"" + field->enum_type()->full_name() +
+ "\" has no value named \"" + proto.default_value() + "\".");
}
} else if (field->enum_type()->value_count() > 0) {
// All enums must have at least one value, or we would have reported
@@ -4878,26 +3933,12 @@ void DescriptorBuilder::CrossLinkField(
field->containing_type()->full_name(),
conflicting_field->name()));
}
- } else {
- if (field->is_extension()) {
- if (!tables_->AddExtension(field)) {
- const FieldDescriptor* conflicting_field =
- tables_->FindExtension(field->containing_type(), field->number());
- string error_msg = strings::Substitute(
- "Extension number $0 has already been used in \"$1\" by extension "
- "\"$2\" defined in $3.",
- field->number(),
- field->containing_type()->full_name(),
- conflicting_field->full_name(),
- conflicting_field->file()->name());
- // Conflicting extension numbers should be an error. However, before
- // turning this into an error we need to fix all existing broken
- // protos first.
- // TODO(xiaofeng): Change this to an error.
- AddWarning(field->full_name(), proto,
- DescriptorPool::ErrorCollector::NUMBER, error_msg);
- }
- }
+ }
+
+ if (field->is_extension()) {
+ // No need for error checking: if the extension number collided,
+ // we've already been informed of it by the if() above.
+ tables_->AddExtension(field);
}
// Add the field to the lowercase-name and camelcase-name tables.
@@ -4916,8 +3957,7 @@ void DescriptorBuilder::CrossLinkEnum(
}
void DescriptorBuilder::CrossLinkEnumValue(
- EnumValueDescriptor* enum_value,
- const EnumValueDescriptorProto& /* proto */) {
+ EnumValueDescriptor* enum_value, const EnumValueDescriptorProto& proto) {
if (enum_value->options_ == NULL) {
enum_value->options_ = &EnumValueOptions::default_instance();
}
@@ -5006,103 +4046,6 @@ void DescriptorBuilder::ValidateFileOptions(FileDescriptor* file,
}
}
}
- if (file->syntax() == FileDescriptor::SYNTAX_PROTO3) {
- ValidateProto3(file, proto);
- }
-}
-
-void DescriptorBuilder::ValidateProto3(
- FileDescriptor* file, const FileDescriptorProto& proto) {
- for (int i = 0; i < file->extension_count(); ++i) {
- ValidateProto3Field(file->extensions_ + i, proto.extension(i));
- }
- for (int i = 0; i < file->message_type_count(); ++i) {
- ValidateProto3Message(file->message_types_ + i, proto.message_type(i));
- }
- for (int i = 0; i < file->enum_type_count(); ++i) {
- ValidateProto3Enum(file->enum_types_ + i, proto.enum_type(i));
- }
- if (IsLite(file)) {
- AddError(file->name(), proto,
- DescriptorPool::ErrorCollector::OTHER,
- "Lite runtime is not supported in proto3.");
- }
-}
-
-void DescriptorBuilder::ValidateProto3Message(
- Descriptor* message, const DescriptorProto& proto) {
- for (int i = 0; i < message->nested_type_count(); ++i) {
- ValidateProto3Message(message->nested_types_ + i,
- proto.nested_type(i));
- }
- for (int i = 0; i < message->enum_type_count(); ++i) {
- ValidateProto3Enum(message->enum_types_ + i,
- proto.enum_type(i));
- }
- for (int i = 0; i < message->field_count(); ++i) {
- ValidateProto3Field(message->fields_ + i, proto.field(i));
- }
- for (int i = 0; i < message->extension_count(); ++i) {
- ValidateProto3Field(message->extensions_ +i, proto.extension(i));
- }
- if (message->extension_range_count() > 0) {
- AddError(message->full_name(), proto,
- DescriptorPool::ErrorCollector::OTHER,
- "Extension ranges are not allowed in proto3.");
- }
- if (message->options().message_set_wire_format()) {
- // Using MessageSet doesn't make sense since we disallow extensions.
- AddError(message->full_name(), proto,
- DescriptorPool::ErrorCollector::OTHER,
- "MessageSet is not supported in proto3.");
- }
-}
-
-void DescriptorBuilder::ValidateProto3Field(
- FieldDescriptor* field, const FieldDescriptorProto& proto) {
- if (field->is_extension() &&
- !AllowedExtendeeInProto3(field->containing_type()->full_name())) {
- AddError(field->full_name(), proto,
- DescriptorPool::ErrorCollector::OTHER,
- "Extensions in proto3 are only allowed for defining options.");
- }
- if (field->is_required()) {
- AddError(field->full_name(), proto,
- DescriptorPool::ErrorCollector::OTHER,
- "Required fields are not allowed in proto3.");
- }
- if (field->has_default_value()) {
- AddError(
- field->full_name(), proto, DescriptorPool::ErrorCollector::OTHER,
- "Explicit default values are not allowed in proto3.");
- }
- if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM &&
- field->enum_type() &&
- field->enum_type()->file()->syntax() != FileDescriptor::SYNTAX_PROTO3) {
- // Proto3 messages can only use Proto3 enum types; otherwise we can't
- // guarantee that the default value is zero.
- AddError(field->full_name(), proto,
- DescriptorPool::ErrorCollector::TYPE,
- "Enum type \"" + field->enum_type()->full_name() +
- "\" is not a proto3 enum, but is used in \"" +
- field->containing_type()->full_name() +
- "\" which is a proto3 message type.");
- }
- bool allow_groups = false;
- if (field->type() == FieldDescriptor::TYPE_GROUP && !allow_groups) {
- AddError(field->full_name(), proto,
- DescriptorPool::ErrorCollector::TYPE,
- "Groups are not supported in proto3 syntax.");
- }
-}
-
-void DescriptorBuilder::ValidateProto3Enum(
- EnumDescriptor* enm, const EnumDescriptorProto& proto) {
- if (enm->value_count() > 0 && enm->value(0)->number() != 0) {
- AddError(
- enm->full_name(), proto, DescriptorPool::ErrorCollector::OTHER,
- "The first enum value must be zero in proto3.");
- }
}
void DescriptorBuilder::ValidateMessageOptions(Descriptor* message,
@@ -5129,6 +4072,10 @@ void DescriptorBuilder::ValidateMessageOptions(Descriptor* message,
void DescriptorBuilder::ValidateFieldOptions(FieldDescriptor* field,
const FieldDescriptorProto& proto) {
+ if (field->options().has_experimental_map_key()) {
+ ValidateMapKey(field, proto);
+ }
+
// Only message type fields may be lazy.
if (field->options().lazy()) {
if (field->type() != FieldDescriptor::TYPE_MESSAGE) {
@@ -5177,16 +4124,6 @@ void DescriptorBuilder::ValidateFieldOptions(FieldDescriptor* field,
"a lite type, but the reverse is allowed.");
}
- // Validate map types.
- if (field->is_map()) {
- if (!ValidateMapEntry(field, proto)) {
- AddError(field->full_name(), proto,
- DescriptorPool::ErrorCollector::OTHER,
- "map_entry should not be set explicitly. Use map<KeyType, "
- "ValueType> instead.");
- }
- }
-
}
void DescriptorBuilder::ValidateEnumOptions(EnumDescriptor* enm,
@@ -5220,8 +4157,7 @@ void DescriptorBuilder::ValidateEnumOptions(EnumDescriptor* enm,
}
void DescriptorBuilder::ValidateEnumValueOptions(
- EnumValueDescriptor* /* enum_value */,
- const EnumValueDescriptorProto& /* proto */) {
+ EnumValueDescriptor* enum_value, const EnumValueDescriptorProto& proto) {
// Nothing to do so far.
}
void DescriptorBuilder::ValidateServiceOptions(ServiceDescriptor* service,
@@ -5239,132 +4175,62 @@ void DescriptorBuilder::ValidateServiceOptions(ServiceDescriptor* service,
VALIDATE_OPTIONS_FROM_ARRAY(service, method, Method);
}
-void DescriptorBuilder::ValidateMethodOptions(MethodDescriptor* /* method */,
- const MethodDescriptorProto& /* proto */) {
+void DescriptorBuilder::ValidateMethodOptions(MethodDescriptor* method,
+ const MethodDescriptorProto& proto) {
// Nothing to do so far.
}
-bool DescriptorBuilder::ValidateMapEntry(FieldDescriptor* field,
- const FieldDescriptorProto& proto) {
- const Descriptor* message = field->message_type();
- if (// Must not contain extensions, extension range or nested message or
- // enums
- message->extension_count() != 0 ||
- field->label() != FieldDescriptor::LABEL_REPEATED ||
- message->extension_range_count() != 0 ||
- message->nested_type_count() != 0 || message->enum_type_count() != 0 ||
- // Must contain exactly two fields
- message->field_count() != 2 ||
- // Field name and message name must match
- message->name() != ToCamelCase(field->name(), false) + "Entry" ||
- // Entry message must be in the same containing type of the field.
- field->containing_type() != message->containing_type()) {
- return false;
+void DescriptorBuilder::ValidateMapKey(FieldDescriptor* field,
+ const FieldDescriptorProto& proto) {
+ if (!field->is_repeated()) {
+ AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+ "map type is only allowed for repeated fields.");
+ return;
}
- const FieldDescriptor* key = message->field(0);
- const FieldDescriptor* value = message->field(1);
- if (key->label() != FieldDescriptor::LABEL_OPTIONAL || key->number() != 1 ||
- key->name() != "key") {
- return false;
- }
- if (value->label() != FieldDescriptor::LABEL_OPTIONAL ||
- value->number() != 2 || value->name() != "value") {
- return false;
+ if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
+ AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+ "map type is only allowed for fields with a message type.");
+ return;
}
- // Check key types are legal.
- switch (key->type()) {
- case FieldDescriptor::TYPE_ENUM:
- AddError(
- field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
- "Key in map fields cannot be enum types.");
- break;
- case FieldDescriptor::TYPE_FLOAT:
- case FieldDescriptor::TYPE_DOUBLE:
- case FieldDescriptor::TYPE_MESSAGE:
- case FieldDescriptor::TYPE_GROUP:
- case FieldDescriptor::TYPE_BYTES:
- AddError(
- field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
- "Key in map fields cannot be float/double, bytes or message types.");
- break;
- case FieldDescriptor::TYPE_BOOL:
- case FieldDescriptor::TYPE_INT32:
- case FieldDescriptor::TYPE_INT64:
- case FieldDescriptor::TYPE_SINT32:
- case FieldDescriptor::TYPE_SINT64:
- case FieldDescriptor::TYPE_STRING:
- case FieldDescriptor::TYPE_UINT32:
- case FieldDescriptor::TYPE_UINT64:
- case FieldDescriptor::TYPE_FIXED32:
- case FieldDescriptor::TYPE_FIXED64:
- case FieldDescriptor::TYPE_SFIXED32:
- case FieldDescriptor::TYPE_SFIXED64:
- // Legal cases
- break;
- // Do not add a default, so that the compiler will complain when new types
- // are added.
+ const Descriptor* item_type = field->message_type();
+ if (item_type == NULL) {
+ AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+ "Could not find field type.");
+ return;
}
- return true;
-}
+ // Find the field in item_type named by "experimental_map_key"
+ const string& key_name = field->options().experimental_map_key();
+ const Symbol key_symbol = LookupSymbol(
+ key_name,
+ // We append ".key_name" to the containing type's name since
+ // LookupSymbol() searches for peers of the supplied name, not
+ // children of the supplied name.
+ item_type->full_name() + "." + key_name);
-void DescriptorBuilder::DetectMapConflicts(const Descriptor* message,
- const DescriptorProto& proto) {
- map<string, const Descriptor*> seen_types;
- for (int i = 0; i < message->nested_type_count(); ++i) {
- const Descriptor* nested = message->nested_type(i);
- pair<map<string, const Descriptor*>::iterator, bool> result =
- seen_types.insert(std::make_pair(nested->name(), nested));
- if (!result.second) {
- if (result.first->second->options().map_entry() ||
- nested->options().map_entry()) {
- AddError(message->full_name(), proto,
- DescriptorPool::ErrorCollector::NAME,
- "Expanded map entry type " + nested->name() +
- " conflicts with an existing nested message type.");
- }
- }
- // Recursively test on the nested types.
- DetectMapConflicts(message->nested_type(i), proto.nested_type(i));
- }
- // Check for conflicted field names.
- for (int i = 0; i < message->field_count(); ++i) {
- const FieldDescriptor* field = message->field(i);
- map<string, const Descriptor*>::iterator iter =
- seen_types.find(field->name());
- if (iter != seen_types.end() && iter->second->options().map_entry()) {
- AddError(message->full_name(), proto,
- DescriptorPool::ErrorCollector::NAME,
- "Expanded map entry type " + iter->second->name() +
- " conflicts with an existing field.");
- }
+ if (key_symbol.IsNull() || key_symbol.field_descriptor->is_extension()) {
+ AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+ "Could not find field named \"" + key_name + "\" in type \"" +
+ item_type->full_name() + "\".");
+ return;
}
- // Check for conflicted enum names.
- for (int i = 0; i < message->enum_type_count(); ++i) {
- const EnumDescriptor* enum_desc = message->enum_type(i);
- map<string, const Descriptor*>::iterator iter =
- seen_types.find(enum_desc->name());
- if (iter != seen_types.end() && iter->second->options().map_entry()) {
- AddError(message->full_name(), proto,
- DescriptorPool::ErrorCollector::NAME,
- "Expanded map entry type " + iter->second->name() +
- " conflicts with an existing enum type.");
- }
+ const FieldDescriptor* key_field = key_symbol.field_descriptor;
+
+ if (key_field->is_repeated()) {
+ AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+ "map_key must not name a repeated field.");
+ return;
}
- // Check for conflicted oneof names.
- for (int i = 0; i < message->oneof_decl_count(); ++i) {
- const OneofDescriptor* oneof_desc = message->oneof_decl(i);
- map<string, const Descriptor*>::iterator iter =
- seen_types.find(oneof_desc->name());
- if (iter != seen_types.end() && iter->second->options().map_entry()) {
- AddError(message->full_name(), proto,
- DescriptorPool::ErrorCollector::NAME,
- "Expanded map entry type " + iter->second->name() +
- " conflicts with an existing oneof type.");
- }
+
+ if (key_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+ "map key must name a scalar or string field.");
+ return;
}
+
+ field->experimental_map_key_ = key_field;
}
@@ -5519,15 +4385,6 @@ bool DescriptorBuilder::OptionInterpreter::InterpretSingleOption(
// so we will just leave it as uninterpreted.
AddWithoutInterpreting(*uninterpreted_option_, options);
return true;
- } else if (!(builder_->undefine_resolved_name_).empty()) {
- // Option is resolved to a name which is not defined.
- return AddNameError(
- "Option \"" + debug_msg_name + "\" is resolved to \"(" +
- builder_->undefine_resolved_name_ +
- ")\", which is not defined. The innermost scope is searched first "
- "in name resolution. Consider using a leading '.'(i.e., \"(." +
- debug_msg_name.substr(1) +
- "\") to start from the outermost scope.");
} else {
return AddNameError("Option \"" + debug_msg_name + "\" unknown.");
}
@@ -5548,15 +4405,14 @@ bool DescriptorBuilder::OptionInterpreter::InterpretSingleOption(
"\" is not a field or extension of message \"" +
descriptor->name() + "\".");
}
+ } else if (field->is_repeated()) {
+ return AddNameError("Option field \"" + debug_msg_name +
+ "\" is repeated. Repeated options are not "
+ "supported.");
} else if (i < uninterpreted_option_->name_size() - 1) {
if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
return AddNameError("Option \"" + debug_msg_name +
"\" is an atomic type, not a message.");
- } else if (field->is_repeated()) {
- return AddNameError("Option field \"" + debug_msg_name +
- "\" is a repeated message. Repeated message "
- "options must be initialized using an "
- "aggregate value.");
} else {
// Drill down into the submessage.
intermediate_fields.push_back(field);
@@ -5573,7 +4429,7 @@ bool DescriptorBuilder::OptionInterpreter::InterpretSingleOption(
// known will populate them correctly.
// First see if the option is already set.
- if (!field->is_repeated() && !ExamineIfOptionIsSet(
+ if (!ExamineIfOptionIsSet(
intermediate_fields.begin(),
intermediate_fields.end(),
field, debug_msg_name,
@@ -5948,16 +4804,14 @@ class AggregateErrorCollector : public io::ErrorCollector {
public:
string error_;
- virtual void AddError(int /* line */, int /* column */,
- const string& message) {
+ virtual void AddError(int line, int column, const string& message) {
if (!error_.empty()) {
error_ += "; ";
}
error_ += message;
}
- virtual void AddWarning(int /* line */, int /* column */,
- const string& /* message */) {
+ virtual void AddWarning(int line, int column, const string& message) {
// Ignore warnings
}
};
@@ -6088,39 +4942,5 @@ void DescriptorBuilder::OptionInterpreter::SetUInt64(int number, uint64 value,
}
}
-void DescriptorBuilder::LogUnusedDependency(const FileDescriptor* result) {
-
- if (!unused_dependency_.empty()) {
- std::set<string> annotation_extensions;
- annotation_extensions.insert("google.protobuf.MessageOptions");
- annotation_extensions.insert("google.protobuf.FileOptions");
- annotation_extensions.insert("google.protobuf.FieldOptions");
- annotation_extensions.insert("google.protobuf.EnumOptions");
- annotation_extensions.insert("google.protobuf.EnumValueOptions");
- annotation_extensions.insert("google.protobuf.ServiceOptions");
- annotation_extensions.insert("google.protobuf.MethodOptions");
- annotation_extensions.insert("google.protobuf.StreamOptions");
- for (set<const FileDescriptor*>::const_iterator
- it = unused_dependency_.begin();
- it != unused_dependency_.end(); ++it) {
- // Do not log warnings for proto files which extend annotations.
- int i;
- for (i = 0 ; i < (*it)->extension_count(); ++i) {
- if (annotation_extensions.find(
- (*it)->extension(i)->containing_type()->full_name())
- != annotation_extensions.end()) {
- break;
- }
- }
- // Log warnings for unused imported files.
- if (i == (*it)->extension_count()) {
- GOOGLE_LOG(WARNING) << "Warning: Unused import: \"" << result->name()
- << "\" imports \"" << (*it)->name()
- << "\" which is not used.";
- }
- }
- }
-}
-
} // namespace protobuf
} // namespace google
« no previous file with comments | « third_party/protobuf/src/google/protobuf/descriptor.h ('k') | third_party/protobuf/src/google/protobuf/descriptor.proto » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698