35 #include <google/protobuf/descriptor.h>
45 #include <unordered_map>
46 #include <unordered_set>
49 #include <google/protobuf/stubs/common.h>
50 #include <google/protobuf/stubs/logging.h>
51 #include <google/protobuf/stubs/stringprintf.h>
52 #include <google/protobuf/stubs/strutil.h>
53 #include <google/protobuf/any.h>
54 #include <google/protobuf/descriptor.pb.h>
55 #include <google/protobuf/stubs/once.h>
56 #include <google/protobuf/io/coded_stream.h>
57 #include <google/protobuf/io/tokenizer.h>
58 #include <google/protobuf/io/zero_copy_stream_impl.h>
59 #include <google/protobuf/descriptor_database.h>
60 #include <google/protobuf/dynamic_message.h>
61 #include <google/protobuf/generated_message_util.h>
62 #include <google/protobuf/text_format.h>
63 #include <google/protobuf/unknown_field_set.h>
64 #include <google/protobuf/wire_format.h>
65 #include <google/protobuf/stubs/casts.h>
66 #include <google/protobuf/stubs/substitute.h>
67 #include <google/protobuf/io/strtod.h>
68 #include <google/protobuf/stubs/map_util.h>
69 #include <google/protobuf/stubs/stl_util.h>
70 #include <google/protobuf/stubs/hash.h>
72 #undef PACKAGE // autoheader #defines this. :(
75 #include <google/protobuf/port_def.inc>
102 #define DEFINE_MEMBERS(TYPE, TYPE_CONSTANT, FIELD) \
103 explicit Symbol(TYPE* value) : ptr_(value) { \
104 value->symbol_type_ = TYPE_CONSTANT; \
106 const TYPE* FIELD() const { \
107 return type() == TYPE_CONSTANT ? static_cast<const TYPE*>(ptr_) : nullptr; \
162 #undef DEFINE_MEMBERS
217 return query_key()->name;
225 const auto or_file = [&](
const void* p) {
return p ? p :
GetFile(); };
231 return {or_file(
field->is_extension() ?
field->extension_scope()
232 :
field->containing_type()),
252 return {query_key()->parent, query_key()->name};
268 return {query_key()->parent, query_key()->field_number};
281 static_cast<CppType
>(0),
364 #if !defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)
374 return (
ch >=
'a' &&
ch <=
'z') ? (
ch -
'a' +
'A') :
ch;
378 return (
ch >=
'A' &&
ch <=
'Z') ? (
ch -
'A' +
'a') :
ch;
382 bool capitalize_next = !lower_first;
386 for (
char character :
input) {
387 if (character ==
'_') {
388 capitalize_next =
true;
389 }
else if (capitalize_next) {
391 capitalize_next =
false;
393 result.push_back(character);
398 if (lower_first && !
result.empty()) {
406 bool capitalize_next =
false;
410 for (
char character :
input) {
411 if (character ==
'_') {
412 capitalize_next =
true;
413 }
else if (capitalize_next) {
415 capitalize_next =
false;
417 result.push_back(character);
425 bool next_upper =
true;
429 for (
char character :
input) {
430 if (character ==
'_') {
446 class PrefixRemover {
450 for (
char character :
prefix) {
451 if (character !=
'_') {
473 for (
i = 0, j = 0;
i <
str.size() && j <
prefix_.size();
i++) {
490 while (
i <
str.size() &&
str[
i] ==
'_') {
495 if (
i ==
str.size()) {
500 str.remove_prefix(
i);
516 typedef std::pair<const void*, StringPiece> PointerStringPair;
518 typedef std::pair<const Descriptor*, int> DescriptorIntPair;
520 #define HASH_MAP std::unordered_map
521 #define HASH_SET std::unordered_set
522 #define HASH_FXN hash
524 template <
typename PairType>
525 struct PointerIntegerPairHash {
526 size_t operator()(
const PairType& p)
const {
527 static const size_t prime1 = 16777499;
528 static const size_t prime2 = 16777619;
529 return reinterpret_cast<size_t>(p.first) * prime1 ^
530 static_cast<size_t>(p.second) * prime2;
535 static const size_t bucket_size = 4;
536 static const size_t min_buckets = 8;
538 inline bool operator()(
const PairType&
a,
const PairType&
b)
const {
543 struct PointerStringPairHash {
544 size_t operator()(
const PointerStringPair& p)
const {
545 static const size_t prime = 16777619;
547 return reinterpret_cast<size_t>(
p.first) * prime ^
548 static_cast<size_t>(string_hash(
p.second));
553 static const size_t bucket_size = 4;
554 static const size_t min_buckets = 8;
556 inline bool operator()(
const PointerStringPair& a,
557 const PointerStringPair&
b)
const {
563 const Symbol kNullSymbol;
565 struct SymbolByFullNameHash {
566 size_t operator()(Symbol s)
const {
567 return HASH_FXN<StringPiece>{}(
s.full_name());
570 struct SymbolByFullNameEq {
571 bool operator()(Symbol a, Symbol
b)
const {
572 return a.full_name() ==
b.full_name();
575 using SymbolsByNameSet =
576 HASH_SET<Symbol, SymbolByFullNameHash, SymbolByFullNameEq>;
578 struct SymbolByParentHash {
579 size_t operator()(Symbol s)
const {
580 return PointerStringPairHash{}(
s.parent_name_key());
583 struct SymbolByParentEq {
584 bool operator()(Symbol a, Symbol
b)
const {
585 return a.parent_name_key() ==
b.parent_name_key();
588 using SymbolsByParentSet =
589 HASH_SET<Symbol, SymbolByParentHash, SymbolByParentEq>;
592 HASH_FXN<StringPiece>>
596 PointerStringPairHash>
599 struct FieldsByNumberHash {
600 size_t operator()(Symbol s)
const {
601 return PointerIntegerPairHash<std::pair<const void*, int>>{}(
602 s.parent_number_key());
605 struct FieldsByNumberEq {
606 bool operator()(Symbol a, Symbol
b)
const {
607 return a.parent_number_key() ==
b.parent_number_key();
610 using FieldsByNumberSet =
611 HASH_SET<Symbol, FieldsByNumberHash, FieldsByNumberEq>;
612 using EnumValuesByNumberSet = FieldsByNumberSet;
618 typedef std::map<DescriptorIntPair, const FieldDescriptor*>
619 ExtensionsGroupedByDescriptorMap;
620 typedef HASH_MAP<std::string, const SourceCodeInfo_Location*>
623 std::set<std::string>* NewAllowedProto3Extendee() {
624 auto allowed_proto3_extendees =
new std::set<std::string>;
625 const char* kOptionNames[] = {
626 "FileOptions",
"MessageOptions",
"FieldOptions",
"EnumOptions",
627 "EnumValueOptions",
"ServiceOptions",
"MethodOptions",
"OneofOptions"};
628 for (
const char* option_name : kOptionNames) {
632 allowed_proto3_extendees->insert(
std::string(
"google.protobuf.") +
636 allowed_proto3_extendees->insert(
std::string(
"proto") +
"2." + option_name);
638 return allowed_proto3_extendees;
646 static auto allowed_proto3_extendees =
648 return allowed_proto3_extendees->find(
name) !=
649 allowed_proto3_extendees->end();
696 return Create<OutOfLineAlloc>(OutOfLineAlloc{::operator
new(
n), n})->
ptr;
699 return AllocRawInternal(n,
static_cast<Tag>(
tag));
705 template <
typename T,
typename...
Args>
707 static_assert(
alignof(
T) <= 8,
"");
708 return ::new (AllocRawInternal(
sizeof(
T), TypeTag<T>(KnownTypes{})))
709 T(std::forward<Args>(
args)...);
714 TableArena(
const TableArena&) =
delete;
715 TableArena& operator=(
const TableArena&) =
delete;
721 for (Block* list : GetLists()) {
722 while (list !=
nullptr) {
725 b->VisitBlock(DestroyVisitor{});
735 void PrintUsageInfo()
const {
737 std::map<uint32_t, uint32_t> unused_space_count;
739 for (;
b !=
nullptr;
b =
b->next) {
740 ++unused_space_count[
b->space_left()];
744 fprintf(
stderr,
" Blocks `At least %d`",
size);
746 fprintf(
stderr,
" Blocks `full`");
749 for (
auto p : unused_space_count) {
750 fprintf(
stderr,
" space=%4u, count=%3u\n",
p.first,
p.second);
754 fprintf(
stderr,
"TableArena unused space histogram:\n");
755 fprintf(
stderr,
" Current: %u\n",
773 Block*
b = info.block;
775 VisitAlloc(
b->data(), &
b->start_offset, &
b->end_offset, DestroyVisitor{},
777 if (--info.count == 0) {
784 auto lists = GetLists();
788 for (Block* list : lists) {
789 while (list !=
nullptr) {
793 if (
b->start_offset == 0) {
797 RelocateToUsedList(
b);
805 void ClearRollbackData() {
811 static constexpr
size_t RoundUp(
size_t n) {
return (n + 7) & ~7; }
813 using Tag =
unsigned char;
819 Block* to_relocate =
nullptr;
820 Block* to_use =
nullptr;
829 if (to_relocate !=
nullptr) {
839 constexpr
size_t kBlockSize = 4096;
840 to_use =
current_ =
::new (::
operator new(kBlockSize)) Block(kBlockSize);
851 void*
p = to_use->Allocate(
size,
tag);
852 if (to_relocate !=
nullptr) {
853 RelocateToUsedList(to_relocate);
858 static void OperatorDelete(
void* p,
size_t s) {
859 #if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation)
860 ::operator
delete(
p,
s);
862 ::operator
delete(
p);
866 struct OutOfLineAlloc {
871 template <
typename...
T>
876 template <
typename T,
typename Visitor>
885 template <
typename Visitor,
typename...
T>
893 using F = void (*)(
char*,
uint16_t*, Visitor);
894 static constexpr
F kFuncs[] = {&RunVisitor<T, Visitor>...};
900 template <
typename U,
typename... Ts>
901 static constexpr
Tag TypeTag(TypeList<U, Ts...>) {
906 typename U,
typename T,
typename... Ts,
908 static constexpr
Tag TypeTag(TypeList<T, Ts...>) {
909 return 1 + TypeTag<U>(TypeList<Ts...>{});
912 template <
typename U>
913 static constexpr
Tag TypeTag(TypeList<>) {
915 return SizeToRawTag(
sizeof(U));
921 std::array<std::string, 2>, std::array<std::string, 3>,
922 std::array<std::string, 4>, std::array<std::string, 5>,
930 struct DestroyVisitor {
931 template <
typename T>
932 void operator()(
T* p) {
935 void operator()(OutOfLineAlloc* p) { OperatorDelete(p->ptr, p->size); }
938 static uint32_t SizeToRawTag(
size_t n) {
return (
RoundUp(n) / 8) - 1; }
954 explicit Block(
uint32_t allocated_size) {
957 reinterpret_cast<char*
>(
this) + allocated_size -
data();
962 return reinterpret_cast<char*
>(
this) +
RoundUp(
sizeof(Block));
966 return data() +
capacity -
reinterpret_cast<char*
>(
this);
978 void Destroy() { OperatorDelete(
this, memory_used()); }
980 void PrependTo(Block*& list) {
985 template <
typename Visitor>
986 void VisitBlock(Visitor
visit) {
988 VisitAlloc(
data(), &s, &e,
visit, KnownTypes{});
993 Block* PopBlock(Block*& list) {
999 void RelocateToUsedList(Block* to_relocate) {
1004 }
else if (
current_->space_left() < to_relocate->space_left()) {
1010 if (to_relocate->space_left() >= 1 +
kSmallSizes[i]) {
1040 struct RollbackInfo {
1054 class DescriptorPool::Tables {
1142 std::vector<const FieldDescriptor*>*
out)
const;
1162 template <
typename Type>
1167 template <
typename Type>
1180 template <
typename... In>
1201 template <
typename Type>
1208 template <
typename Type>
1275 const void* parent,
StringPiece lowercase_name)
const;
1277 const void* parent,
StringPiece camelcase_name)
const;
1303 std::pair<const FileDescriptorTables*, const SourceCodeInfo*>* p);
1334 mutable EnumValuesByNumberSet unknown_enum_values_by_number_
1370 : fields_by_lowercase_name_tmp_(
new FieldsByNameMap()),
1371 fields_by_camelcase_name_tmp_(
new FieldsByNameMap()) {}
1376 static auto file_descriptor_tables =
1378 return *file_descriptor_tables;
1387 checkpoints_.pop_back();
1388 if (checkpoints_.empty()) {
1391 symbols_after_checkpoint_.clear();
1392 files_after_checkpoint_.clear();
1393 extensions_after_checkpoint_.clear();
1394 arena_.ClearRollbackData();
1400 const CheckPoint&
checkpoint = checkpoints_.back();
1402 for (
size_t i =
checkpoint.pending_symbols_before_checkpoint;
1403 i < symbols_after_checkpoint_.size(); i++) {
1404 Symbol::QueryKey
name;
1405 name.name = symbols_after_checkpoint_[
i];
1406 symbols_by_name_.erase(Symbol(&
name));
1408 for (
size_t i =
checkpoint.pending_files_before_checkpoint;
1409 i < files_after_checkpoint_.size(); i++) {
1410 files_by_name_.erase(files_after_checkpoint_[i]);
1412 for (
size_t i =
checkpoint.pending_extensions_before_checkpoint;
1413 i < extensions_after_checkpoint_.size(); i++) {
1414 extensions_.erase(extensions_after_checkpoint_[i]);
1417 symbols_after_checkpoint_.resize(
1418 checkpoint.pending_symbols_before_checkpoint);
1419 files_after_checkpoint_.resize(
checkpoint.pending_files_before_checkpoint);
1420 extensions_after_checkpoint_.resize(
1421 checkpoint.pending_extensions_before_checkpoint);
1424 checkpoints_.pop_back();
1433 return it == symbols_by_name_.end() ? kNullSymbol : *
it;
1440 query.parent = parent;
1442 return it == symbols_by_parent_.end() ? kNullSymbol : *
it;
1447 if (
pool->mutex_ !=
nullptr) {
1450 if (known_bad_symbols_.empty() && known_bad_files_.empty()) {
1456 if (
pool->fallback_database_ !=
nullptr) {
1457 known_bad_symbols_.clear();
1458 known_bad_files_.clear();
1462 if (
result.IsNull() &&
pool->underlay_ !=
nullptr) {
1469 if (
pool->TryFindSymbolInFallbackDatabase(
name)) {
1486 if (parent !=
nullptr &&
1487 1 <=
number && number <= parent->sequential_field_limit_) {
1492 query.parent = parent;
1496 return it == fields_by_number_.end() ? nullptr :
it->field_descriptor();
1501 if (
field->is_extension()) {
1502 if (
field->extension_scope() ==
nullptr) {
1503 return field->file();
1505 return field->extension_scope();
1508 return field->containing_type();
1514 tables->FieldsByLowercaseNamesLazyInitInternal();
1518 for (Symbol symbol : symbols_by_parent_) {
1520 if (!
field)
continue;
1521 PointerStringPair lowercase_key(FindParentForFieldsByMap(
field),
1522 field->lowercase_name().c_str());
1528 const void* parent,
StringPiece lowercase_name)
const {
1530 fields_by_lowercase_name_once_,
1533 PointerStringPair(parent, lowercase_name));
1542 for (Symbol symbol : symbols_by_parent_) {
1544 if (!
field)
continue;
1545 PointerStringPair camelcase_key(FindParentForFieldsByMap(
field),
1546 field->camelcase_name().c_str());
1552 const void* parent,
StringPiece camelcase_name)
const {
1554 fields_by_camelcase_name_once_,
1557 PointerStringPair(parent, camelcase_name));
1570 Symbol::QueryKey
query;
1571 query.parent = parent;
1574 auto it = enum_values_by_number_.find(Symbol(&
query));
1575 return it == enum_values_by_number_.end() ? nullptr
1576 :
it->enum_value_descriptor();
1584 const auto*
value = FindEnumValueByNumber(parent,
number);
1585 if (
value !=
nullptr) {
1590 Symbol::QueryKey
query;
1591 query.parent = parent;
1597 auto it = unknown_enum_values_by_number_.find(Symbol(&
query));
1598 if (
it != unknown_enum_values_by_number_.end() &&
1599 it->enum_value_descriptor() !=
nullptr) {
1600 return it->enum_value_descriptor();
1607 auto it = unknown_enum_values_by_number_.find(Symbol(&
query));
1608 if (
it != unknown_enum_values_by_number_.end() &&
1609 it->enum_value_descriptor() !=
nullptr) {
1610 return it->enum_value_descriptor();
1618 parent->name().c_str(),
number);
1620 auto* tables =
const_cast<DescriptorPool::Tables*
>(
pool->tables_.get());
1624 MutexLockMaybe l2(
pool->mutex_);
1626 result->all_names_ = tables->AllocateStringArray(
1628 StrCat(parent->full_name(),
".", enum_value_name));
1645 std::vector<const FieldDescriptor*>*
out)
const {
1646 ExtensionsGroupedByDescriptorMap::const_iterator
it =
1647 extensions_.lower_bound(std::make_pair(extendee, 0));
1648 for (;
it != extensions_.end() &&
it->first.first == extendee; ++
it) {
1649 out->push_back(
it->second);
1658 if (symbols_by_name_.insert(symbol).second) {
1659 symbols_after_checkpoint_.push_back(full_name.c_str());
1671 return symbols_by_parent_.insert(symbol).second;
1676 files_after_checkpoint_.push_back(
file->
name().c_str());
1685 fields_by_lowercase_name_tmp_ =
nullptr;
1686 fields_by_camelcase_name_tmp_ =
nullptr;
1691 const void* parent = FindParentForFieldsByMap(
field);
1700 PointerStringPair lowercase_key(parent,
field->lowercase_name().c_str());
1702 lowercase_key,
field)) {
1704 &fields_by_lowercase_name_, lowercase_key,
1705 FindPtrOrNull(*fields_by_lowercase_name_tmp_, lowercase_key));
1708 PointerStringPair camelcase_key(parent,
field->camelcase_name().c_str());
1710 camelcase_key,
field)) {
1712 &fields_by_camelcase_name_, camelcase_key,
1713 FindPtrOrNull(*fields_by_camelcase_name_tmp_, camelcase_key));
1719 if (
field->containing_type() !=
nullptr &&
field->number() >= 1 &&
1720 field->number() <=
field->containing_type()->sequential_field_limit_) {
1721 if (
field->is_extension()) {
1730 return fields_by_number_.insert(
Symbol(
field)).second;
1735 const int base =
value->type()->value(0)->number();
1736 if (base <= value->
number() &&
1744 DescriptorIntPair
key(
field->containing_type(),
field->number());
1746 extensions_after_checkpoint_.push_back(
key);
1755 template <
typename Type>
1757 return reinterpret_cast<Type*
>(AllocateBytes(
sizeof(
Type)));
1760 template <
typename Type>
1762 return reinterpret_cast<Type*
>(AllocateBytes(
sizeof(
Type) *
count));
1771 char* p = AllocateArray<char>(
static_cast<int>(
value.size() + 1));
1773 p[
value.size()] = 0;
1777 template <
typename... In>
1781 return array.data();
1784 DescriptorPool::Tables::FieldNamesResult
1793 if (opt_json_name !=
nullptr) {
1794 json_name = *opt_json_name;
1796 json_name = ToJsonName(
name);
1799 const bool lower_eq_name = lowercase_name ==
name;
1800 const bool camel_eq_name = camelcase_name ==
name;
1801 const bool json_eq_name = json_name ==
name;
1802 const bool json_eq_camel = json_name == camelcase_name;
1804 const int total_count = 2 + (lower_eq_name ? 0 : 1) +
1805 (camel_eq_name ? 0 : 1) +
1806 (json_eq_name || json_eq_camel ? 0 : 1);
1809 switch (total_count) {
1825 if (scope.empty()) {
1831 if (lower_eq_name) {
1832 result.lowercase_index = 0;
1838 if (camel_eq_name) {
1839 result.camelcase_index = 0;
1847 }
else if (json_eq_camel) {
1857 template <
typename Type>
1862 template <
typename Type>
1872 if (
size == 0)
return nullptr;
1877 std::pair<const FileDescriptorTables*, const SourceCodeInfo*>* p) {
1878 for (
int i = 0,
len = p->second->location_size(); i <
len; ++i) {
1880 p->first->locations_by_path_[
Join(
loc->path(),
",")] =
loc;
1886 std::pair<const FileDescriptorTables*, const SourceCodeInfo*>
p(
1887 std::make_pair(
this, info));
1911 ErrorCollector* error_collector)
1956 MutexLockMaybe lock(
mutex_);
1965 EncodedDescriptorDatabase* GeneratedDatabase() {
1966 static auto generated_database =
1968 return generated_database;
1980 return GeneratedDatabase();
1998 const void* encoded_file_descriptor,
int size) {
2033 MutexLockMaybe lock(
mutex_);
2035 tables_->known_bad_symbols_.clear();
2036 tables_->known_bad_files_.clear();
2053 MutexLockMaybe lock(
mutex_);
2055 tables_->known_bad_symbols_.clear();
2056 tables_->known_bad_files_.clear();
2063 if (file_result !=
nullptr)
return file_result;
2074 return tables_->FindByNameHelper(
this,
name).descriptor();
2080 tables_->FindByNameHelper(
this,
name).field_descriptor()) {
2081 if (!
field->is_extension()) {
2091 tables_->FindByNameHelper(
this,
name).field_descriptor()) {
2092 if (
field->is_extension()) {
2101 return tables_->FindByNameHelper(
this,
name).oneof_descriptor();
2106 return tables_->FindByNameHelper(
this,
name).enum_descriptor();
2111 return tables_->FindByNameHelper(
this,
name).enum_value_descriptor();
2116 return tables_->FindByNameHelper(
this,
name).service_descriptor();
2121 return tables_->FindByNameHelper(
this,
name).method_descriptor();
2126 if (extendee->extension_range_count() == 0)
return nullptr;
2136 MutexLockMaybe lock(
mutex_);
2138 tables_->known_bad_symbols_.clear();
2139 tables_->known_bad_files_.clear();
2179 if (
result !=
nullptr &&
result->containing_type() == extendee) {
2185 if (
type !=
nullptr) {
2187 const int type_extension_count =
type->extension_count();
2188 for (
int i = 0;
i < type_extension_count;
i++) {
2190 if (
extension->containing_type() == extendee &&
2204 std::vector<const FieldDescriptor*>*
out)
const {
2205 MutexLockMaybe lock(
mutex_);
2207 tables_->known_bad_symbols_.clear();
2208 tables_->known_bad_files_.clear();
2214 tables_->extensions_loaded_from_db_.count(extendee) == 0) {
2215 std::vector<int> numbers;
2218 for (
int number : numbers) {
2223 tables_->extensions_loaded_from_db_.insert(extendee);
2248 file()->tables_->FindFieldByLowercaseName(
this,
key);
2259 file()->tables_->FindFieldByCamelcaseName(
this,
key);
2269 file()->tables_->FindNestedSymbol(
this,
key).field_descriptor();
2274 return file()->tables_->FindNestedSymbol(
this,
key).oneof_descriptor();
2280 file()->tables_->FindNestedSymbol(
this,
key).field_descriptor();
2287 file()->tables_->FindFieldByLowercaseName(
this,
key);
2298 file()->tables_->FindFieldByCamelcaseName(
this,
key);
2307 return file()->tables_->FindNestedSymbol(
this,
key).descriptor();
2312 return file()->tables_->FindNestedSymbol(
this,
key).enum_descriptor();
2317 return file()->tables_->FindNestedSymbol(
this,
key).enum_value_descriptor();
2321 if (!
options().map_entry())
return nullptr;
2327 if (!
options().map_entry())
return nullptr;
2334 return file()->tables_->FindNestedSymbol(
this,
key).enum_value_descriptor();
2338 return file()->tables_->FindEnumValueByNumber(
this,
key);
2343 return file()->tables_->FindEnumValueByNumberCreatingIfUnknown(
this,
key);
2348 return file()->tables_->FindNestedSymbol(
this,
key).method_descriptor();
2353 return tables_->FindNestedSymbol(
this,
key).descriptor();
2358 return tables_->FindNestedSymbol(
this,
key).enum_descriptor();
2363 return tables_->FindNestedSymbol(
this,
key).enum_value_descriptor();
2368 return tables_->FindNestedSymbol(
this,
key).service_descriptor();
2374 tables_->FindNestedSymbol(
this,
key).field_descriptor();
2407 const Descriptor::ExtensionRange*
2411 for (
int i = 0;
i < extension_range_count();
i++) {
2412 if (
number >= extension_range(i)->start &&
2413 number < extension_range(i)->end) {
2414 return extension_range(i);
2423 for (
int i = 0;
i < reserved_range_count();
i++) {
2431 const EnumDescriptor::ReservedRange*
2434 for (
int i = 0;
i < reserved_range_count();
i++) {
2450 if (
tables_->known_bad_files_.count(name_string) > 0)
return false;
2464 std::string::size_type dot_pos =
prefix.find_last_of(
'.');
2465 if (dot_pos == std::string::npos) {
2488 if (
tables_->known_bad_symbols_.count(name_string) > 0)
return false;
2515 ||
tables_->FindFile(file_proto.
name()) !=
nullptr
2536 if (
tables_->FindFile(file_proto.
name()) !=
nullptr) {
2553 return type_descriptor_.message_type->options().map_entry();
2557 bool quote_string_type)
const {
2558 GOOGLE_CHECK(has_default_value()) <<
"No default value";
2561 return StrCat(default_value_int32_t());
2563 return StrCat(default_value_int64_t());
2564 case CPPTYPE_UINT32:
2565 return StrCat(default_value_uint32_t());
2566 case CPPTYPE_UINT64:
2567 return StrCat(default_value_uint64_t());
2570 case CPPTYPE_DOUBLE:
2573 return default_value_bool() ?
"true" :
"false";
2574 case CPPTYPE_STRING:
2575 if (quote_string_type) {
2576 return "\"" +
CEscape(default_value_string()) +
"\"";
2578 if (
type() == TYPE_BYTES) {
2579 return CEscape(default_value_string());
2581 return default_value_string();
2585 return default_value_enum()->name();
2586 case CPPTYPE_MESSAGE:
2587 GOOGLE_LOG(DFATAL) <<
"Messages can't have default values!";
2590 GOOGLE_LOG(
FATAL) <<
"Can't get here: failed to get default value as string";
2602 for (
int i = 0;
i < dependency_count();
i++) {
2606 for (
int i = 0;
i < public_dependency_count();
i++) {
2610 for (
int i = 0;
i < weak_dependency_count();
i++) {
2614 for (
int i = 0;
i < message_type_count();
i++) {
2617 for (
int i = 0;
i < enum_type_count();
i++) {
2620 for (
int i = 0;
i < service_count();
i++) {
2623 for (
int i = 0;
i < extension_count();
i++) {
2635 GOOGLE_LOG(
ERROR) <<
"Cannot copy json_name to a proto of a different size.";
2638 for (
int i = 0;
i < message_type_count();
i++) {
2641 for (
int i = 0;
i < extension_count();
i++) {
2647 if (source_code_info_ &&
2656 for (
int i = 0;
i < field_count();
i++) {
2659 for (
int i = 0;
i < oneof_decl_count();
i++) {
2662 for (
int i = 0;
i < nested_type_count();
i++) {
2665 for (
int i = 0;
i < enum_type_count();
i++) {
2668 for (
int i = 0;
i < extension_range_count();
i++) {
2671 for (
int i = 0;
i < extension_count();
i++) {
2674 for (
int i = 0;
i < reserved_range_count();
i++) {
2679 for (
int i = 0;
i < reserved_name_count();
i++) {
2692 GOOGLE_LOG(
ERROR) <<
"Cannot copy json_name to a proto of a different size.";
2695 for (
int i = 0;
i < field_count();
i++) {
2698 for (
int i = 0;
i < nested_type_count();
i++) {
2701 for (
int i = 0;
i < extension_count();
i++) {
2709 if (has_json_name_) {
2712 if (proto3_optional_) {
2718 implicit_cast<int>(
label())));
2720 implicit_cast<int>(
type())));
2722 if (is_extension()) {
2729 if (
cpp_type() == CPPTYPE_MESSAGE) {
2740 }
else if (
cpp_type() == CPPTYPE_ENUM) {
2741 if (!
enum_type()->is_unqualified_placeholder_) {
2747 if (has_default_value()) {
2774 for (
int i = 0;
i < value_count();
i++) {
2777 for (
int i = 0;
i < reserved_range_count();
i++) {
2782 for (
int i = 0;
i < reserved_name_count();
i++) {
2803 for (
int i = 0;
i < method_count();
i++) {
2815 if (!input_type()->is_unqualified_placeholder_) {
2820 if (!output_type()->is_unqualified_placeholder_) {
2829 if (client_streaming_) {
2832 if (server_streaming_) {
2841 bool RetrieveOptionsAssumingRightPool(
2843 std::vector<std::string>* option_entries) {
2844 option_entries->clear();
2845 const Reflection* reflection =
options.GetReflection();
2846 std::vector<const FieldDescriptor*>
fields;
2851 if (
field->is_repeated()) {
2855 for (
int j = 0;
j <
count;
j++) {
2860 printer.SetExpandAny(
true);
2861 printer.SetInitialIndentLevel(
depth + 1);
2864 fieldval.append(
"{\n");
2865 fieldval.append(
tmp);
2866 fieldval.append(
depth * 2,
' ');
2867 fieldval.append(
"}");
2873 if (
field->is_extension()) {
2878 option_entries->push_back(
name +
" = " + fieldval);
2881 return !option_entries->empty();
2887 std::vector<std::string>* option_entries) {
2892 if (
options.GetDescriptor()->file()->pool() ==
pool) {
2893 return RetrieveOptionsAssumingRightPool(
depth,
options, option_entries);
2896 pool->FindMessageTypeByName(
options.GetDescriptor()->full_name());
2897 if (option_descriptor ==
nullptr) {
2900 return RetrieveOptionsAssumingRightPool(
depth,
options, option_entries);
2903 std::unique_ptr<Message> dynamic_options(
2904 factory.GetPrototype(option_descriptor)->New());
2907 reinterpret_cast<const uint8_t*
>(serialized.c_str()),
2909 input.SetExtensionRegistry(
pool, &factory);
2910 if (dynamic_options->ParseFromCodedStream(&
input)) {
2911 return RetrieveOptionsAssumingRightPool(
depth, *dynamic_options,
2915 <<
options.GetDescriptor()->full_name();
2916 return RetrieveOptionsAssumingRightPool(
depth,
options, option_entries);
2925 std::vector<std::string> all_options;
2929 return !all_options.empty();
2936 std::vector<std::string> all_options;
2942 return !all_options.empty();
2945 class SourceLocationCommentPrinter {
2947 template <
typename DescType>
2949 const DebugStringOptions&
options)
2957 const std::vector<int>&
path,
2959 const DebugStringOptions&
options)
2969 for (
const std::string& leading_detached_comment :
2971 *
output += FormatComment(leading_detached_comment);
2991 std::vector<std::string>
lines =
Split(stripped_comment,
"\n");
3011 return DebugStringWithOptions(
options);
3015 const DebugStringOptions& debug_string_options)
const {
3018 std::vector<int>
path;
3020 SourceLocationCommentPrinter syntax_comment(
this,
path,
"",
3021 debug_string_options);
3022 syntax_comment.AddPreComment(&
contents);
3025 syntax_comment.AddPostComment(&
contents);
3028 SourceLocationCommentPrinter comment_printer(
this,
"", debug_string_options);
3029 comment_printer.AddPreComment(&
contents);
3031 std::set<int> public_dependencies;
3032 std::set<int> weak_dependencies;
3033 public_dependencies.insert(public_dependencies_,
3034 public_dependencies_ + public_dependency_count_);
3035 weak_dependencies.insert(weak_dependencies_,
3036 weak_dependencies_ + weak_dependency_count_);
3038 for (
int i = 0;
i < dependency_count();
i++) {
3039 if (public_dependencies.count(i) > 0) {
3041 dependency(i)->
name());
3042 }
else if (weak_dependencies.count(i) > 0) {
3044 dependency(i)->
name());
3047 dependency(i)->
name());
3051 if (!package().
empty()) {
3052 std::vector<int>
path;
3054 SourceLocationCommentPrinter package_comment(
this,
path,
"",
3055 debug_string_options);
3056 package_comment.AddPreComment(&
contents);
3058 package_comment.AddPostComment(&
contents);
3065 for (
int i = 0;
i < enum_type_count();
i++) {
3072 std::set<const Descriptor*>
groups;
3073 for (
int i = 0;
i < extension_count();
i++) {
3079 for (
int i = 0;
i < message_type_count();
i++) {
3087 for (
int i = 0;
i < service_count();
i++) {
3093 for (
int i = 0;
i < extension_count();
i++) {
3095 if (i > 0)
contents.append(
"}\n\n");
3102 if (extension_count() > 0)
contents.append(
"}\n\n");
3104 comment_printer.AddPostComment(&
contents);
3111 return DebugStringWithOptions(
options);
3115 const DebugStringOptions&
options)
const {
3122 const DebugStringOptions& debug_string_options,
3123 bool include_opening_clause)
const {
3131 SourceLocationCommentPrinter comment_printer(
this,
prefix,
3132 debug_string_options);
3133 comment_printer.AddPreComment(
contents);
3135 if (include_opening_clause) {
3145 std::set<const Descriptor*>
groups;
3146 for (
int i = 0;
i < field_count();
i++) {
3151 for (
int i = 0;
i < extension_count();
i++) {
3157 for (
int i = 0;
i < nested_type_count();
i++) {
3158 if (
groups.count(nested_type(i)) == 0) {
3159 nested_type(i)->DebugString(
depth,
contents, debug_string_options,
3163 for (
int i = 0;
i < enum_type_count();
i++) {
3166 for (
int i = 0;
i < field_count();
i++) {
3167 if (
field(i)->real_containing_oneof() ==
nullptr) {
3172 debug_string_options);
3176 for (
int i = 0;
i < extension_range_count();
i++) {
3178 extension_range(i)->
start,
3179 extension_range(i)->
end - 1);
3184 for (
int i = 0;
i < extension_count();
i++) {
3193 if (extension_count() > 0)
3196 if (reserved_range_count() > 0) {
3198 for (
int i = 0;
i < reserved_range_count();
i++) {
3212 if (reserved_name_count() > 0) {
3214 for (
int i = 0;
i < reserved_name_count();
i++) {
3222 comment_printer.AddPostComment(
contents);
3227 return DebugStringWithOptions(
options);
3231 const DebugStringOptions& debug_string_options)
const {
3234 if (is_extension()) {
3240 if (is_extension()) {
3254 return kTypeToName[
type()];
3277 if (is_map() || real_containing_oneof() ||
3278 (is_optional() && !has_optional_keyword())) {
3282 SourceLocationCommentPrinter comment_printer(
this,
prefix,
3283 debug_string_options);
3284 comment_printer.AddPreComment(
contents);
3290 bool bracketed =
false;
3291 if (has_default_value()) {
3294 DefaultValueAsString(
true));
3296 if (has_json_name_) {
3303 contents->append(
"json_name = \"");
3310 &formatted_options)) {
3311 contents->append(bracketed ?
", " :
" [");
3313 contents->append(formatted_options);
3320 if (
type() == TYPE_GROUP) {
3331 comment_printer.AddPostComment(
contents);
3336 return DebugStringWithOptions(
options);
3340 const DebugStringOptions&
options)
const {
3348 const DebugStringOptions& debug_string_options)
const {
3351 SourceLocationCommentPrinter comment_printer(
this,
prefix,
3352 debug_string_options);
3353 comment_printer.AddPreComment(
contents);
3359 if (debug_string_options.elide_oneof_body) {
3363 for (
int i = 0;
i < field_count();
i++) {
3368 comment_printer.AddPostComment(
contents);
3373 return DebugStringWithOptions(
options);
3377 const DebugStringOptions&
options)
const {
3385 const DebugStringOptions& debug_string_options)
const {
3389 SourceLocationCommentPrinter comment_printer(
this,
prefix,
3390 debug_string_options);
3391 comment_printer.AddPreComment(
contents);
3397 for (
int i = 0;
i < value_count();
i++) {
3401 if (reserved_range_count() > 0) {
3403 for (
int i = 0;
i < reserved_range_count();
i++) {
3407 }
else if (
range->end == INT_MAX) {
3417 if (reserved_name_count() > 0) {
3419 for (
int i = 0;
i < reserved_name_count();
i++) {
3428 comment_printer.AddPostComment(
contents);
3433 return DebugStringWithOptions(
options);
3437 const DebugStringOptions&
options)
const {
3445 const DebugStringOptions& debug_string_options)
const {
3448 SourceLocationCommentPrinter comment_printer(
this,
prefix,
3449 debug_string_options);
3450 comment_printer.AddPreComment(
contents);
3456 &formatted_options)) {
3461 comment_printer.AddPostComment(
contents);
3466 return DebugStringWithOptions(
options);
3470 const DebugStringOptions&
options)
const {
3478 const DebugStringOptions& debug_string_options)
const {
3479 SourceLocationCommentPrinter comment_printer(
this,
"",
3480 debug_string_options);
3481 comment_printer.AddPreComment(
contents);
3487 for (
int i = 0;
i < method_count();
i++) {
3493 comment_printer.AddPostComment(
contents);
3498 return DebugStringWithOptions(
options);
3502 const DebugStringOptions&
options)
const {
3510 const DebugStringOptions& debug_string_options)
const {
3514 SourceLocationCommentPrinter comment_printer(
this,
prefix,
3515 debug_string_options);
3516 comment_printer.AddPreComment(
contents);
3520 input_type()->full_name(), output_type()->full_name(),
3525 &formatted_options)) {
3532 comment_printer.AddPostComment(
contents);
3541 if (source_code_info_) {
3543 tables_->GetSourceLocation(
path, source_code_info_)) {
3545 if (span.
size() == 3 || span.
size() == 4) {
3546 out_location->start_line = span.Get(0);
3547 out_location->start_column = span.Get(1);
3548 out_location->end_line = span.Get(span.
size() == 3 ? 0 : 2);
3549 out_location->end_column = span.Get(span.
size() - 1);
3551 out_location->leading_comments =
loc->leading_comments();
3552 out_location->trailing_comments =
loc->trailing_comments();
3553 out_location->leading_detached_comments.assign(
3554 loc->leading_detached_comments().begin(),
3555 loc->leading_detached_comments().end());
3564 std::vector<int>
path;
3565 return GetSourceLocation(
path, out_location);
3569 if (!is_packable())
return false;
3578 std::vector<int>
path;
3579 GetLocationPath(&
path);
3580 return file()->GetSourceLocation(
path, out_location);
3584 std::vector<int>
path;
3585 GetLocationPath(&
path);
3586 return file()->GetSourceLocation(
path, out_location);
3590 std::vector<int>
path;
3591 GetLocationPath(&
path);
3596 std::vector<int>
path;
3597 GetLocationPath(&
path);
3598 return file()->GetSourceLocation(
path, out_location);
3602 std::vector<int>
path;
3603 GetLocationPath(&
path);
3604 return service()->file()->GetSourceLocation(
path, out_location);
3608 std::vector<int>
path;
3609 GetLocationPath(&
path);
3610 return file()->GetSourceLocation(
path, out_location);
3615 std::vector<int>
path;
3616 GetLocationPath(&
path);
3617 return type()->file()->GetSourceLocation(
path, out_location);
3632 if (is_extension()) {
3633 if (extension_scope() ==
nullptr) {
3637 extension_scope()->GetLocationPath(
output);
3691 struct OptionsToInterpret {
3693 const std::vector<int>&
path,
const Message* orig_opt,
3712 DescriptorPool::ErrorCollector* error_collector);
3718 friend class OptionInterpreter;
3724 DescriptorPool::Tables*
tables_;
3730 std::vector<OptionsToInterpret> options_to_interpret_;
3736 std::set<const FileDescriptor*> dependencies_;
3740 std::set<const FileDescriptor*> unused_dependency_;
3769 void AddNotDefinedError(
3796 bool build_it =
true);
3801 bool build_it =
true);
3821 ResolveMode resolve_mode = LOOKUP_ALL,
3822 bool build_it =
true);
3828 ResolveMode resolve_mode = LOOKUP_ALL,
3829 bool build_it =
true);
3834 bool AddSymbol(
const std::string& full_name,
const void* parent,
3852 template <
typename Type>
3861 template <
class DescriptorT>
3863 DescriptorT*
descriptor,
int options_field_tag,
3866 void AllocateOptions(
const FileOptions& orig_options,
3870 template <
class DescriptorT>
3871 void AllocateOptionsImpl(
3874 DescriptorT*
descriptor,
const std::vector<int>& options_path,
3893 BuildFieldOrExtension(proto, parent,
result,
false);
3897 BuildFieldOrExtension(proto, parent,
result,
true);
3901 Descriptor::ExtensionRange*
result);
3904 Descriptor::ReservedRange*
result);
3907 EnumDescriptor::ReservedRange*
result);
3934 void CrossLinkExtensionRange(Descriptor::ExtensionRange*
range,
3946 void InterpretOptions();
3949 class OptionInterpreter {
3956 ~OptionInterpreter();
3961 bool InterpretOptions(OptionsToInterpret* options_to_interpret);
3967 class AggregateOptionFinder;
3977 const std::vector<int>& src_path,
3978 const std::vector<int>& options_path);
3989 bool ExamineIfOptionIsSet(
3990 std::vector<const FieldDescriptor*>::const_iterator
3991 intermediate_fields_iter,
3992 std::vector<const FieldDescriptor*>::const_iterator
3993 intermediate_fields_end,
4023 builder_->AddError(options_to_interpret_->element_name,
4024 *uninterpreted_option_, location,
msg);
4031 #ifdef PROTOBUF_INTERNAL_IGNORE_FIELD_NAME_ERRORS_
4033 #else // PROTOBUF_INTERNAL_IGNORE_FIELD_NAME_ERRORS_
4035 #endif // PROTOBUF_INTERNAL_IGNORE_FIELD_NAME_ERRORS_
4050 const OptionsToInterpret* options_to_interpret_;
4061 std::map<std::vector<int>, std::vector<int>> interpreted_paths_;
4066 std::map<std::vector<int>,
int> repeated_option_counts_;
4082 friend class OptionInterpreter;
4083 friend class OptionInterpreter::AggregateOptionFinder;
4086 return pool->allow_unknown_;
4089 return pool->enforce_weak_;
4095 if (
pool->mutex_ !=
nullptr) {
4096 pool->mutex_->AssertHeld();
4116 void ValidateExtensionRangeOptions(
4117 const std::string& full_name, Descriptor::ExtensionRange* extension_range,
4147 <<
"Cannot call BuildFile on a DescriptorPool that uses a "
4148 "DescriptorDatabase. You must instead find a way to get your file "
4149 "into the underlying database.";
4151 tables_->known_bad_symbols_.clear();
4152 tables_->known_bad_files_.clear();
4159 <<
"Cannot call BuildFile on a DescriptorPool that uses a "
4160 "DescriptorDatabase. You must instead find a way to get your file "
4161 "into the underlying database.";
4163 tables_->known_bad_symbols_.clear();
4164 tables_->known_bad_files_.clear();
4172 if (
tables_->known_bad_files_.count(proto.
name()) > 0) {
4186 DescriptorPool::ErrorCollector* error_collector)
4191 possible_undeclared_dependency_(nullptr),
4192 undefine_resolved_name_(
"") {}
4226 "\"" + undefined_symbol +
"\" is not defined.");
4231 "\" seems to be defined in \"" +
4236 "\". To use it here, please "
4237 "add the necessary import.");
4241 "\"" + undefined_symbol +
"\" is resolved to \"" +
4243 "\", which is not defined. "
4244 "The innermost scope is searched first in name resolution. "
4245 "Consider using a leading '.'(i.e., \"." +
4246 undefined_symbol +
"\") to start from the outermost scope.");
4266 (
file->package().
size() == package_name.size() ||
4267 file->package()[package_name.size()] ==
'.');
4272 for (
int i = 0;
file !=
nullptr &&
i <
file->public_dependency_count();
i++) {
4281 MutexLockMaybe lock((
pool ==
pool_) ?
nullptr :
pool->mutex_);
4284 if (
result.IsNull() &&
pool->underlay_ !=
nullptr) {
4297 if (build_it &&
pool->TryFindSymbolInFallbackDatabase(
name)) {
4343 for (std::set<const FileDescriptor*>::const_iterator
it =
4358 ResolveMode resolve_mode,
bool build_it) {
4362 if (!
name.empty() &&
name[0] ==
'.') {
4378 std::string::size_type name_dot_pos =
name.find_first_of(
'.');
4380 if (name_dot_pos == std::string::npos) {
4381 first_part_of_name =
name;
4383 first_part_of_name =
name.substr(0, name_dot_pos);
4390 std::string::size_type dot_pos = scope_to_try.find_last_of(
'.');
4391 if (dot_pos == std::string::npos) {
4394 scope_to_try.erase(dot_pos);
4398 std::string::size_type
old_size = scope_to_try.size();
4399 scope_to_try.append(1,
'.');
4400 scope_to_try.append(first_part_of_name);
4403 if (first_part_of_name.size() <
name.size()) {
4406 if (
result.IsAggregate()) {
4407 scope_to_try.append(
name, first_part_of_name.size(),
4408 name.size() - first_part_of_name.size());
4446 bool last_was_period =
false;
4448 for (
char character :
name) {
4450 if ((
'a' <= character && character <=
'z') ||
4451 (
'A' <= character && character <=
'Z') ||
4452 (
'0' <= character && character <=
'9') || (character ==
'_')) {
4453 last_was_period =
false;
4454 }
else if (character ==
'.') {
4455 if (last_was_period)
return false;
4456 last_was_period =
true;
4462 return !
name.empty() && !last_was_period;
4482 if (
name[0] ==
'.') {
4484 placeholder_full_name =
name.substr(1);
4486 placeholder_full_name =
name;
4489 std::string::size_type dotpos = placeholder_full_name.
find_last_of(
'.');
4490 if (dotpos != std::string::npos) {
4491 placeholder_package =
4492 tables_->AllocateString(placeholder_full_name.
substr(0, dotpos));
4493 placeholder_name = placeholder_full_name.
substr(dotpos + 1);
4496 placeholder_name = placeholder_full_name;
4501 StrCat(placeholder_full_name,
".placeholder.proto"));
4502 placeholder_file->
package_ = placeholder_package;
4509 memset(
static_cast<void*
>(placeholder_enum), 0,
sizeof(*placeholder_enum));
4511 placeholder_enum->all_names_ =
4512 tables_->AllocateStringArray(placeholder_name, placeholder_full_name);
4513 placeholder_enum->file_ = placeholder_file;
4515 placeholder_enum->is_placeholder_ =
true;
4516 placeholder_enum->is_unqualified_placeholder_ = (
name[0] !=
'.');
4519 placeholder_enum->value_count_ = 1;
4522 placeholder_enum->sequential_value_limit_ = -1;
4525 memset(
static_cast<void*
>(placeholder_value), 0,
4526 sizeof(*placeholder_value));
4530 "PLACEHOLDER_VALUE", placeholder_package->empty()
4531 ?
"PLACEHOLDER_VALUE"
4532 : *placeholder_package +
".PLACEHOLDER_VALUE");
4534 placeholder_value->
number_ = 0;
4535 placeholder_value->
type_ = placeholder_enum;
4538 return Symbol(placeholder_enum);
4544 memset(
static_cast<void*
>(placeholder_message), 0,
4545 sizeof(*placeholder_message));
4547 placeholder_message->all_names_ =
4548 tables_->AllocateStringArray(placeholder_name, placeholder_full_name);
4549 placeholder_message->file_ = placeholder_file;
4551 placeholder_message->is_placeholder_ =
true;
4552 placeholder_message->is_unqualified_placeholder_ = (
name[0] !=
'.');
4555 placeholder_message->extension_range_count_ = 1;
4556 placeholder_message->extension_ranges_ =
4557 tables_->AllocateArray<Descriptor::ExtensionRange>(1);
4558 placeholder_message->extension_ranges_->start = 1;
4560 placeholder_message->extension_ranges_->end =
4562 placeholder_message->extension_ranges_->options_ =
nullptr;
4565 return Symbol(placeholder_message);
4581 memset(
static_cast<void*
>(placeholder), 0,
sizeof(*placeholder));
4585 placeholder->
pool_ =
this;
4602 if (parent ==
nullptr) parent =
file_;
4604 if (full_name.find(
'\0') != std::string::npos) {
4606 "\"" + full_name +
"\" contains null character.");
4609 if (
tables_->AddSymbol(full_name, symbol)) {
4615 <<
"\" not previously defined in "
4616 "symbols_by_name_, but was defined in "
4617 "symbols_by_parent_; this shouldn't be possible.";
4624 if (other_file ==
file_) {
4625 std::string::size_type dot_pos = full_name.find_last_of(
'.');
4626 if (dot_pos == std::string::npos) {
4628 "\"" + full_name +
"\" is already defined.");
4631 "\"" + full_name.substr(dot_pos + 1) +
4632 "\" is already defined in \"" +
4633 full_name.substr(0, dot_pos) +
"\".");
4638 "\"" + full_name +
"\" is already defined in file \"" +
4639 (other_file ==
nullptr ?
"null" : other_file->name()) +
4648 if (
name.find(
'\0') != std::string::npos) {
4650 "\"" +
name +
"\" contains null character.");
4656 if (existing_symbol.IsNull()) {
4657 auto*
package = tables_->AllocateArray<Symbol::Package>(1);
4662 package->file =
file;
4665 std::string::size_type dot_pos =
name.find_last_of(
'.');
4666 if (dot_pos == std::string::npos) {
4678 "\" is already defined (as something other than "
4679 "a package) in file \"" +
4680 existing_symbol.GetFile()->name() +
"\".");
4691 for (
char character :
name) {
4693 if ((character <
'a' ||
'z' < character) &&
4694 (character <
'A' ||
'Z' < character) &&
4695 (character <
'0' ||
'9' < character) && (character !=
'_')) {
4697 "\"" +
name +
"\" is not a valid identifier.");
4707 template <
class DescriptorT>
4710 DescriptorT*
descriptor,
int options_field_tag,
4712 std::vector<int> options_path;
4714 options_path.push_back(options_field_tag);
4716 orig_options,
descriptor, options_path, option_name);
4722 std::vector<int> options_path;
4727 "google.protobuf.FileOptions");
4730 template <
class DescriptorT>
4734 DescriptorT*
descriptor,
const std::vector<int>& options_path,
4743 if (!orig_options.IsInitialized()) {
4746 "Uninterpreted option is missing name or value.");
4754 options->ParseFromString(orig_options.SerializeAsString());
4764 if (
options->uninterpreted_option_size() > 0) {
4771 const UnknownFieldSet& unknown_fields = orig_options.unknown_fields();
4772 if (!unknown_fields.
empty()) {
4780 msg_symbol.descriptor(), unknown_fields.
field(
i).
number());
4791 #define BUILD_ARRAY(INPUT, OUTPUT, NAME, METHOD, PARENT) \
4792 OUTPUT->NAME##_count_ = INPUT.NAME##_size(); \
4793 AllocateArray(INPUT.NAME##_size(), &OUTPUT->NAME##s_); \
4794 for (int i = 0; i < INPUT.NAME##_size(); i++) { \
4795 METHOD(INPUT.NAME(i), PARENT, OUTPUT->NAME##s_ + i); \
4800 std::string error_message(
"File recursively imports itself: ");
4801 for (
size_t i = from_here;
i <
tables_->pending_files_.size();
i++) {
4802 error_message.append(
tables_->pending_files_[
i]);
4803 error_message.append(
" -> ");
4805 error_message.append(proto.
name());
4807 if (
static_cast<size_t>(from_here) <
tables_->pending_files_.size() - 1) {
4830 "\" was not found or had errors.";
4839 existing_file->
CopyTo(&existing_proto);
4848 return existing_proto.SerializeAsString() == proto.SerializeAsString();
4861 if (existing_file !=
nullptr) {
4865 return existing_file;
4880 for (
size_t i = 0;
i <
tables_->pending_files_.size();
i++) {
4902 tables_->pending_files_.pop_back();
4913 tables_->ClearLastCheckpoint();
4914 result->finished_building_ =
true;
4916 tables_->RollbackToLastCheckpoint();
4927 result->is_placeholder_ =
false;
4928 result->finished_building_ =
false;
4933 result->source_code_info_ = info;
4943 "Missing field: FileDescriptorProto.name.");
4948 if (proto.
syntax().empty() || proto.
syntax() ==
"proto2") {
4950 }
else if (proto.
syntax() ==
"proto3") {
4955 "Unrecognized syntax: " + proto.
syntax());
4970 if (
result->name().find(
'\0') != std::string::npos) {
4972 "\"" +
result->name() +
"\" contains null character.");
4979 "A file with this name is already in the pool.");
4984 if (!
result->package().empty()) {
4989 std::set<std::string> seen_dependencies;
4993 result->dependencies_once_ =
nullptr;
4995 std::set<int> weak_deps;
5000 if (!seen_dependencies.insert(proto.
dependency(i)).second) {
5009 if (dependency ==
result) {
5016 if (dependency ==
nullptr) {
5032 (dependency->public_dependency_count() == 0)) {
5037 result->dependencies_[
i] = dependency;
5039 if (
result->dependencies_once_ ==
nullptr) {
5040 result->dependencies_once_ =
5041 tables_->Create<FileDescriptor::LazyInitData>();
5042 result->dependencies_once_->dependencies_names =
5045 std::fill_n(
result->dependencies_once_->dependencies_names,
5050 result->dependencies_once_->dependencies_names[
i] =
5056 int public_dependency_count = 0;
5057 result->public_dependencies_ =
5063 result->public_dependencies_[public_dependency_count++] =
index;
5073 "Invalid public dependency index.");
5076 result->public_dependency_count_ = public_dependency_count;
5084 for (
int i = 0;
i <
result->dependency_count();
i++) {
5090 int weak_dependency_count = 0;
5091 result->weak_dependencies_ =
5096 result->weak_dependencies_[weak_dependency_count++] =
index;
5099 "Invalid weak dependency index.");
5102 result->weak_dependency_count_ = weak_dependency_count;
5111 result->options_ =
nullptr;
5129 option_interpreter.InterpretOptions(&(*
iter));
5132 if (info !=
nullptr) {
5133 option_interpreter.UpdateSourceCodeInfo(info);
5170 if (scope.empty()) {
5171 return tables_->AllocateStringArray(proto_name, proto_name);
5173 return tables_->AllocateStringArray(proto_name,
5174 StrCat(scope,
".", proto_name));
5187 result->containing_type_ = parent;
5188 result->is_placeholder_ =
false;
5189 result->is_unqualified_placeholder_ =
false;
5194 result->well_known_type_ =
it->second;
5203 result->sequential_field_limit_ = 0;
5207 result->sequential_field_limit_ =
i + 1;
5221 result->reserved_name_count_ = reserved_name_count;
5222 result->reserved_names_ =
5224 for (
int i = 0;
i < reserved_name_count; ++
i) {
5230 result->options_ =
nullptr;
5234 "google.protobuf.MessageOptions");
5247 "already-defined range $2 to $3.",
5249 range1.
start(), range1.
end() - 1));
5254 HASH_SET<std::string> reserved_name_set;
5257 if (reserved_name_set.find(
name) == reserved_name_set.end()) {
5258 reserved_name_set.insert(
name);
5267 for (
int i = 0;
i <
result->field_count();
i++) {
5269 for (
int j = 0;
j <
result->extension_range_count();
j++) {
5270 const Descriptor::ExtensionRange*
range =
result->extension_range(j);
5276 "Extension range $0 to $1 includes field \"$2\" ($3).",
5280 for (
int j = 0;
j <
result->reserved_range_count();
j++) {
5281 const Descriptor::ReservedRange*
range =
result->reserved_range(j);
5289 if (reserved_name_set.find(
field->name()) != reserved_name_set.end()) {
5300 for (
int i = 0;
i <
result->extension_range_count();
i++) {
5301 const Descriptor::ExtensionRange* range1 =
result->extension_range(i);
5302 for (
int j = 0;
j <
result->reserved_range_count();
j++) {
5303 const Descriptor::ReservedRange* range2 =
result->reserved_range(j);
5304 if (range1->end > range2->start && range2->end > range1->start) {
5308 "reserved range $2 to $3.",
5309 range1->start, range1->end - 1, range2->start,
5313 for (
int j = i + 1;
j <
result->extension_range_count();
j++) {
5314 const Descriptor::ExtensionRange* range2 =
result->extension_range(j);
5315 if (range1->end > range2->start && range2->end > range1->start) {
5319 "already-defined range $2 to $3.",
5320 range2->start, range2->end - 1, range1->start,
5330 bool is_extension) {
5336 auto all_names =
tables_->AllocateFieldNames(
5337 proto.
name(), scope,
5339 result->all_names_ = all_names.array;
5340 result->lowercase_name_index_ = all_names.lowercase_index;
5341 result->camelcase_name_index_ = all_names.camelcase_index;
5342 result->json_name_index_ = all_names.json_index;
5348 result->is_extension_ = is_extension;
5349 result->is_oneof_ =
false;
5355 "The [proto3_optional=true] option may only be set on proto3"
5365 implicit_cast<int>(proto.
type()));
5367 implicit_cast<int>(proto.
label()));
5371 if (
result->is_extension_) {
5379 "The extension " +
result->full_name() +
" cannot be required.");
5384 result->containing_type_ =
nullptr;
5385 result->type_once_ =
nullptr;
5386 result->default_value_enum_ =
nullptr;
5392 "Repeated fields can't have default values.");
5397 char* end_pos =
nullptr;
5398 switch (
result->cpp_type()) {
5400 result->default_value_int32_t_ =
5404 result->default_value_int64_t_ =
5408 result->default_value_uint32_t_ =
5412 result->default_value_uint64_t_ =
5417 result->default_value_float_ =
5418 std::numeric_limits<float>::infinity();
5420 result->default_value_float_ =
5421 -std::numeric_limits<float>::infinity();
5423 result->default_value_float_ =
5424 std::numeric_limits<float>::quiet_NaN();
5432 result->default_value_double_ =
5433 std::numeric_limits<double>::infinity();
5435 result->default_value_double_ =
5436 -std::numeric_limits<double>::infinity();
5438 result->default_value_double_ =
5439 std::numeric_limits<double>::quiet_NaN();
5441 result->default_value_double_ =
5447 result->default_value_bool_ =
true;
5449 result->default_value_bool_ =
false;
5453 "Boolean default must be true or false.");
5458 result->default_value_enum_ =
nullptr;
5465 result->default_value_string_ =
5472 "Messages can't have default values.");
5473 result->has_default_value_ =
false;
5474 result->default_generated_instance_ =
nullptr;
5478 if (end_pos !=
nullptr) {
5491 switch (
result->cpp_type()) {
5493 result->default_value_int32_t_ = 0;
5496 result->default_value_int64_t_ = 0;
5499 result->default_value_uint32_t_ = 0;
5502 result->default_value_uint64_t_ = 0;
5505 result->default_value_float_ = 0.0f;
5508 result->default_value_double_ = 0.0;
5511 result->default_value_bool_ =
false;
5515 result->default_value_enum_ =
nullptr;
5521 result->default_generated_instance_ =
nullptr;
5527 if (
result->number() <= 0) {
5529 "Field numbers must be positive integers.");
5546 "Field numbers $0 through $1 are reserved for the protocol "
5547 "buffer library implementation.",
5556 "FieldDescriptorProto.extendee not set for extension field.");
5559 result->scope_.extension_scope = parent;
5563 "FieldDescriptorProto.oneof_index should not be set for "
5570 "FieldDescriptorProto.extendee set for non-extension field.");
5573 result->containing_type_ = parent;
5581 "out of range for type \"$1\".",
5584 result->is_oneof_ =
true;
5585 result->scope_.containing_oneof =
5592 result->options_ =
nullptr;
5596 "google.protobuf.FieldOptions");
5605 Descriptor::ExtensionRange*
result) {
5608 if (
result->start <= 0) {
5610 "Extension numbers must be positive integers.");
5620 "Extension range end number must be greater than start number.");
5623 result->options_ =
nullptr;
5625 std::vector<int> options_path;
5632 options_path.push_back(
index);
5636 "google.protobuf.ExtensionRangeOptions");
5642 Descriptor::ReservedRange*
result) {
5645 if (
result->start <= 0) {
5647 "Reserved numbers must be positive integers.");
5659 "Reserved range end number must be greater than start number.");
5669 result->containing_type_ = parent;
5672 result->field_count_ = 0;
5673 result->fields_ =
nullptr;
5674 result->options_ =
nullptr;
5680 "google.protobuf.OneofOptions");
5714 PrefixRemover remover(
result->name());
5715 std::map<std::string, const EnumValueDescriptor*>
values;
5716 for (
int i = 0;
i <
result->value_count();
i++) {
5719 EnumValueToPascalCase(remover.MaybeRemove(
value->name()));
5721 insert_result =
values.insert(std::make_pair(stripped,
value));
5722 bool inserted = insert_result.second;
5730 if (!
inserted && insert_result.first->second->name() !=
value->name() &&
5731 insert_result.first->second->number() !=
value->number()) {
5733 "Enum name " +
value->name() +
" has the same name as " +
5734 values[stripped]->name() +
5735 " if you ignore case and strip out the enum name prefix (if any). "
5736 "This is error-prone and can lead to undefined behavior. "
5737 "Please avoid doing this. If you are using allow_alias, please "
5738 "assign the same numeric value to both enums.";
5756 (parent ==
nullptr) ?
file_->
package() : parent->full_name();
5761 result->containing_type_ = parent;
5762 result->is_placeholder_ =
false;
5763 result->is_unqualified_placeholder_ =
false;
5769 "Enums must contain at least one value.");
5781 proto.
value(i).number() ==
5784 result->sequential_value_limit_ =
i;
5792 result->reserved_name_count_ = reserved_name_count;
5793 result->reserved_names_ =
5795 for (
int i = 0;
i < reserved_name_count; ++
i) {
5803 result->options_ =
nullptr;
5807 "google.protobuf.EnumOptions");
5822 "already-defined range $2 to $3.",
5829 HASH_SET<std::string> reserved_name_set;
5832 if (reserved_name_set.find(
name) == reserved_name_set.end()) {
5833 reserved_name_set.insert(
name);
5841 for (
int i = 0;
i <
result->value_count();
i++) {
5843 for (
int j = 0;
j <
result->reserved_range_count();
j++) {
5844 const EnumDescriptor::ReservedRange*
range =
result->reserved_range(j);
5852 if (reserved_name_set.find(
value->name()) != reserved_name_set.end()) {
5867 size_t scope_len = parent->full_name().size() - parent->name().size();
5868 full_name.reserve(scope_len + proto.
name().size());
5869 full_name.append(parent->full_name().data(), scope_len);
5870 full_name.append(proto.
name());
5880 result->options_ =
nullptr;
5884 "google.protobuf.EnumValueOptions");
5890 bool added_to_outer_scope =
5901 if (added_to_inner_scope && !added_to_outer_scope) {
5906 if (parent->containing_type() ==
nullptr) {
5909 outer_scope = parent->containing_type()->full_name();
5912 if (outer_scope.empty()) {
5913 outer_scope =
"the global scope";
5915 outer_scope =
"\"" + outer_scope +
"\"";
5919 "Note that enum values use C++ scoping rules, meaning that "
5920 "enum values are siblings of their type, not children of it. "
5922 result->name() +
"\" must be unique within " + outer_scope +
5923 ", not just within \"" + parent->name() +
"\".");
5942 result->options_ =
nullptr;
5946 "google.protobuf.ServiceOptions");
5956 result->service_ = parent;
5962 result->input_type_.Init();
5963 result->output_type_.Init();
5966 result->options_ =
nullptr;
5970 "google.protobuf.MethodOptions");
5985 if (
file->options_ ==
nullptr) {
5989 for (
int i = 0;
i <
file->message_type_count();
i++) {
5993 for (
int i = 0;
i <
file->extension_count();
i++) {
5997 for (
int i = 0;
i <
file->enum_type_count();
i++) {
6001 for (
int i = 0;
i <
file->service_count();
i++) {
6008 if (
message->options_ ==
nullptr) {
6012 for (
int i = 0;
i <
message->nested_type_count();
i++) {
6016 for (
int i = 0;
i <
message->enum_type_count();
i++) {
6020 for (
int i = 0;
i <
message->field_count();
i++) {
6024 for (
int i = 0;
i <
message->extension_count();
i++) {
6028 for (
int i = 0;
i <
message->extension_range_count();
i++) {
6036 for (
int i = 0;
i <
message->field_count();
i++) {
6038 if (oneof_decl !=
nullptr) {
6045 if (oneof_decl->field_count() > 0 &&
6046 message->field(i - 1)->containing_oneof() != oneof_decl) {
6050 "Fields in the same oneof must be defined consecutively. "
6051 "\"$0\" cannot be defined before the completion of the "
6052 "\"$1\" oneof definition.",
6053 message->field(i - 1)->name(), oneof_decl->name()));
6057 auto& out_oneof_decl =
message->oneof_decls_[oneof_decl->index()];
6058 if (out_oneof_decl.field_count_ == 0) {
6059 out_oneof_decl.fields_ =
message->field(i);
6069 ++out_oneof_decl.field_count_;
6074 for (
int i = 0;
i <
message->oneof_decl_count();
i++) {
6077 if (oneof_decl->field_count() == 0) {
6080 "Oneof must have at least one field.");
6083 if (oneof_decl->options_ ==
nullptr) {
6088 for (
int i = 0;
i <
message->field_count();
i++) {
6090 if (
field->proto3_optional_) {
6091 if (!
field->containing_oneof() ||
6092 !
field->containing_oneof()->is_synthetic()) {
6095 "Fields with proto3_optional set must be "
6096 "a member of a one-field oneof");
6102 int first_synthetic = -1;
6103 for (
int i = 0;
i <
message->oneof_decl_count();
i++) {
6105 if (oneof->is_synthetic()) {
6106 if (first_synthetic == -1) {
6107 first_synthetic =
i;
6110 if (first_synthetic != -1) {
6113 "Synthetic oneofs must be after all other oneofs");
6118 if (first_synthetic == -1) {
6121 message->real_oneof_decl_count_ = first_synthetic;
6126 Descriptor::ExtensionRange*
range,
6128 if (
range->options_ ==
nullptr) {
6135 if (
field->options_ ==
nullptr) {
6146 if (extendee.IsNull()) {
6154 "\"" + proto.
extendee() +
"\" is not a message type.");
6157 field->containing_type_ = extendee.descriptor();
6159 const Descriptor::ExtensionRange* extension_range =
6160 field->containing_type()->FindExtensionRangeContainingNumber(
6163 if (extension_range ==
nullptr) {
6168 proto.
extendee() ==
"google.protobuf.bridge.MessageSet";
6173 "extension number.",
6174 field->containing_type()->full_name(),
6180 if (
field->containing_oneof() !=
nullptr) {
6186 "Fields of oneofs must themselves have label LABEL_OPTIONAL.");
6213 if (
type.IsNull()) {
6220 field->lazy_default_value_enum_name_ =
6230 if (
field->is_extension()) {
6240 if (
type.IsNull()) {
6258 "\"" + proto.
type_name() +
"\" is not a type.");
6264 field->type_descriptor_.message_type =
type.descriptor();
6265 if (
field->type_descriptor_.message_type ==
nullptr) {
6268 "\"" + proto.
type_name() +
"\" is not a message type.");
6272 if (
field->has_default_value()) {
6275 "Messages can't have default values.");
6278 field->type_descriptor_.enum_type =
type.enum_descriptor();
6279 if (
field->type_descriptor_.enum_type ==
nullptr) {
6282 "\"" + proto.
type_name() +
"\" is not an enum type.");
6286 if (
field->enum_type()->is_placeholder_) {
6289 field->has_default_value_ =
false;
6292 if (
field->has_default_value()) {
6301 "Default value for an enum field must be an identifier.");
6308 field->enum_type()->full_name())
6311 if (default_value !=
nullptr &&
6312 default_value->type() ==
field->enum_type()) {
6313 field->default_value_enum_ = default_value;
6317 "Enum type \"" +
field->enum_type()->full_name() +
6322 }
else if (
field->enum_type()->value_count() > 0) {
6326 field->default_value_enum_ =
field->enum_type()->value(0);
6330 "Field with primitive type has type_name.");
6336 "Field with message or enum type missing type_name.");
6350 field->containing_type() ==
nullptr
6352 :
field->containing_type()->full_name();
6353 if (
field->is_extension()) {
6357 "in \"$1\" by extension \"$2\".",
6358 field->number(), containing_type_name,
6359 conflicting_field->full_name()));
6364 "\"$1\" by field \"$2\".",
6365 field->number(), containing_type_name,
6366 conflicting_field->name()));
6369 if (
field->is_extension()) {
6374 field->containing_type() ==
nullptr
6376 :
field->containing_type()->full_name();
6378 "Extension number $0 has already been used in \"$1\" by extension "
6379 "\"$2\" defined in $3.",
6380 field->number(), containing_type_name,
6381 conflicting_field->full_name(), conflicting_field->file()->name());
6399 for (
int i = 0;
i <
enum_type->value_count();
i++) {
6407 if (enum_value->options_ ==
nullptr) {
6414 if (
service->options_ ==
nullptr) {
6418 for (
int i = 0;
i <
service->method_count();
i++) {
6433 if (input_type.IsNull()) {
6444 "\"" + proto.
input_type() +
"\" is not a message type.");
6446 method->input_type_.Set(input_type.descriptor());
6449 Symbol output_type =
6453 if (output_type.IsNull()) {
6464 "\"" + proto.
output_type() +
"\" is not a message type.");
6466 method->output_type_.Set(output_type.descriptor());
6472 #define VALIDATE_OPTIONS_FROM_ARRAY(descriptor, array_name, type) \
6473 for (int i = 0; i < descriptor->array_name##_count(); ++i) { \
6474 Validate##type##Options(descriptor->array_name##s_ + i, \
6475 proto.array_name(i)); \
6483 return file !=
nullptr &&
6497 for (
int i = 0;
i <
file->dependency_count();
i++) {
6500 file->dependency(i)->
name(), proto,
6502 "Files that do not use optimize_for = LITE_RUNTIME cannot import "
6503 "files which do use this option. This file is not lite, but it "
6505 file->dependency(i)->
name() +
"\" which is.");
6517 for (
int i = 0;
i <
file->extension_count(); ++
i) {
6520 for (
int i = 0;
i <
file->message_type_count(); ++
i) {
6523 for (
int i = 0;
i <
file->enum_type_count(); ++
i) {
6530 for (
char character :
name) {
6531 if (character !=
'_') {
6532 if (character >=
'A' && character <=
'Z') {
6533 result.push_back(character -
'A' +
'a');
6535 result.push_back(character);
6544 for (
int i = 0;
i <
message->nested_type_count(); ++
i) {
6547 for (
int i = 0;
i <
message->enum_type_count(); ++
i) {
6550 for (
int i = 0;
i <
message->field_count(); ++
i) {
6553 for (
int i = 0;
i <
message->extension_count(); ++
i) {
6556 if (
message->extension_range_count() > 0) {
6559 "Extension ranges are not allowed in proto3.");
6561 if (
message->options().message_set_wire_format()) {
6564 "MessageSet is not supported in proto3.");
6570 std::map<std::string, const FieldDescriptor*> name_to_field;
6571 for (
int i = 0;
i <
message->field_count(); ++
i) {
6574 if (name_to_field.find(lowercase_name) != name_to_field.end()) {
6577 "The JSON camel-case name of field \"" +
6578 message->field(i)->name() +
"\" conflicts with field \"" +
6579 name_to_field[lowercase_name]->name() +
"\". This is not " +
6580 "allowed in proto3.");
6582 name_to_field[lowercase_name] =
message->field(i);
6589 if (
field->is_extension() &&
6590 !AllowedExtendeeInProto3(
field->containing_type()->full_name())) {
6593 "Extensions in proto3 are only allowed for defining options.");
6595 if (
field->is_required()) {
6597 "Required fields are not allowed in proto3.");
6599 if (
field->has_default_value()) {
6602 "Explicit default values are not allowed in proto3.");
6605 field->enum_type() &&
6611 "Enum type \"" +
field->enum_type()->full_name() +
6612 "\" is not a proto3 enum, but is used in \"" +
6613 field->containing_type()->full_name() +
6614 "\" which is a proto3 message type.");
6618 "Groups are not supported in proto3 syntax.");
6624 if (enm->value_count() > 0 && enm->value(0)->number() != 0) {
6627 "The first enum value must be zero in proto3.");
6638 const int64_t max_extension_range =
6639 static_cast<int64_t>(
message->options().message_set_wire_format()
6642 for (
int i = 0;
i <
message->extension_range_count(); ++
i) {
6643 if (
message->extension_range(i)->end > max_extension_range + 1) {
6647 max_extension_range));
6651 message->extension_ranges_ + i,
6663 if (
field->options().lazy()) {
6666 "[lazy = true] can only be specified for submessage fields.");
6671 if (
field->options().packed() && !
field->is_packable()) {
6674 "[packed = true] can only be specified for repeated primitive fields.");
6679 if (
field->containing_type_ !=
nullptr &&
6680 &
field->containing_type()->options() !=
6682 field->containing_type()->options().message_set_wire_format()) {
6683 if (
field->is_extension()) {
6684 if (!
field->is_optional() ||
6688 "Extensions of MessageSets must be optional messages.");
6692 "MessageSets cannot have fields, only extensions.");
6701 "Extensions to non-lite types can only be declared in non-lite "
6702 "files. Note that you cannot extend a non-lite type to contain "
6703 "a lite type, but the reverse is allowed.");
6707 if (
field->is_map()) {
6710 "map_entry should not be set explicitly. Use map<KeyType, "
6711 "ValueType> instead.");
6726 if (
field->is_extension() &&
6727 (
field->has_json_name() &&
6728 field->json_name() != ToJsonName(
field->name()))) {
6731 "option json_name is not allowed on extension fields.");
6739 if (!enm->options().has_allow_alias() || !enm->options().allow_alias()) {
6740 std::map<int, std::string> used_values;
6741 for (
int i = 0;
i < enm->value_count(); ++
i) {
6743 if (used_values.find(enum_value->
number()) != used_values.end()) {
6745 "\"" + enum_value->full_name() +
6746 "\" uses the same enum value as \"" +
6747 used_values[enum_value->
number()] +
6748 "\". If this is intended, set "
6749 "'option allow_alias = true;' to the enum definition.";
6750 if (!enm->options().allow_alias()) {
6756 used_values[enum_value->
number()] = enum_value->full_name();
6769 const std::string& full_name, Descriptor::ExtensionRange* extension_range,
6772 (void)extension_range;
6778 (
service->file()->options().cc_generic_services() ||
6779 service->file()->options().java_generic_services())) {
6781 "Files with optimize_for = LITE_RUNTIME cannot define services "
6782 "unless you set both options cc_generic_services and "
6783 "java_generic_services to false.");
6799 message->extension_count() != 0 ||
6801 message->extension_range_count() != 0 ||
6802 message->nested_type_count() != 0 ||
message->enum_type_count() != 0 ||
6804 message->field_count() != 2 ||
6808 field->containing_type() !=
message->containing_type()) {
6815 key->name() !=
"key") {
6819 value->number() != 2 ||
value->name() !=
"value") {
6824 switch (
key->type()) {
6827 "Key in map fields cannot be enum types.");
6836 "Key in map fields cannot be float/double, bytes or message types.");
6857 if (
value->enum_type()->value(0)->number() != 0) {
6859 "Enum value in map must define 0 as the first value.");
6868 std::map<std::string, const Descriptor*> seen_types;
6869 for (
int i = 0;
i <
message->nested_type_count(); ++
i) {
6872 seen_types.insert(std::make_pair(
nested->name(),
nested));
6874 if (
result.first->second->options().map_entry() ||
6875 nested->options().map_entry()) {
6878 "Expanded map entry type " +
nested->name() +
6879 " conflicts with an existing nested message type.");
6886 for (
int i = 0;
i <
message->field_count(); ++
i) {
6889 seen_types.find(
field->name());
6890 if (
iter != seen_types.end() &&
iter->second->options().map_entry()) {
6893 "Expanded map entry type " +
iter->second->name() +
6894 " conflicts with an existing field.");
6898 for (
int i = 0;
i <
message->enum_type_count(); ++
i) {
6901 seen_types.find(enum_desc->name());
6902 if (
iter != seen_types.end() &&
iter->second->options().map_entry()) {
6905 "Expanded map entry type " +
iter->second->name() +
6906 " conflicts with an existing enum type.");
6910 for (
int i = 0;
i <
message->oneof_decl_count(); ++
i) {
6913 seen_types.find(oneof_desc->name());
6914 if (
iter != seen_types.end() &&
iter->second->options().map_entry()) {
6917 "Expanded map entry type " +
iter->second->name() +
6918 " conflicts with an existing oneof type.");
6931 switch (
field->type()) {
6944 "Illegal jstype for int64, uint64, sint64, fixed64 "
6945 "or sfixed64 field: " +
6952 "jstype is only allowed on int64, uint64, sint64, fixed64 "
6953 "or sfixed64 fields.");
6958 #undef VALIDATE_OPTIONS_FROM_ARRAY
6971 OptionsToInterpret* options_to_interpret) {
6977 bool failed =
false;
6983 options->GetDescriptor()->FindFieldByName(
"uninterpreted_option");
6985 <<
"No field named \"uninterpreted_option\" in the Options proto.";
6986 options->GetReflection()->ClearField(
options, uninterpreted_options_field);
6988 std::vector<int> src_path = options_to_interpret->element_path;
6989 src_path.push_back(uninterpreted_options_field->number());
6994 "uninterpreted_option");
6995 GOOGLE_CHECK(original_uninterpreted_options_field !=
nullptr)
6996 <<
"No field named \"uninterpreted_option\" in the Options proto.";
6998 const int num_uninterpreted_options =
7001 for (
int i = 0;
i < num_uninterpreted_options; ++
i) {
7002 src_path.push_back(i);
7003 uninterpreted_option_ = down_cast<const UninterpretedOption*>(
7006 if (!InterpretSingleOption(
options, src_path,
7007 options_to_interpret->element_path)) {
7012 src_path.pop_back();
7015 uninterpreted_option_ =
nullptr;
7029 std::unique_ptr<Message> unparsed_options(
options->New());
7033 if (!unparsed_options->AppendToString(&
buf) ||
7038 "Some options could not be correctly parsed using the proto "
7039 "descriptors compiled into this binary.\n"
7040 "Unparsed options: " +
7041 unparsed_options->ShortDebugString() +
7043 "Parsing attempt: " +
7055 const std::vector<int>& options_path) {
7057 if (uninterpreted_option_->name_size() == 0) {
7060 return AddNameError(
"Option must have a name.");
7062 if (uninterpreted_option_->name(0).name_part() ==
"uninterpreted_option") {
7063 return AddNameError(
7064 "Option must not use reserved name "
7065 "\"uninterpreted_option\".");
7068 const Descriptor* options_descriptor =
nullptr;
7079 Symbol symbol = builder_->FindSymbolNotEnforcingDeps(
7080 options->GetDescriptor()->full_name());
7081 options_descriptor = symbol.descriptor();
7082 if (options_descriptor ==
nullptr) {
7086 options_descriptor =
options->GetDescriptor();
7098 std::vector<const FieldDescriptor*> intermediate_fields;
7101 std::vector<int> dest_path = options_path;
7103 for (
int i = 0;
i < uninterpreted_option_->name_size(); ++
i) {
7104 builder_->undefine_resolved_name_.clear();
7105 const std::string& name_part = uninterpreted_option_->name(i).name_part();
7106 if (debug_msg_name.size() > 0) {
7107 debug_msg_name +=
".";
7109 if (uninterpreted_option_->name(i).is_extension()) {
7110 debug_msg_name +=
"(" + name_part +
")";
7118 field = symbol.field_descriptor();
7124 debug_msg_name += name_part;
7129 if (
field ==
nullptr) {
7133 AddWithoutInterpreting(*uninterpreted_option_,
options);
7135 }
else if (!(builder_->undefine_resolved_name_).empty()) {
7137 return AddNameError(
7138 "Option \"" + debug_msg_name +
"\" is resolved to \"(" +
7139 builder_->undefine_resolved_name_ +
7140 ")\", which is not defined. The innermost scope is searched first "
7141 "in name resolution. Consider using a leading '.'(i.e., \"(." +
7142 debug_msg_name.substr(1) +
7143 "\") to start from the outermost scope.");
7145 return AddNameError(
7146 "Option \"" + debug_msg_name +
7147 "\" unknown. Ensure that your proto" +
7148 " definition file imports the proto which defines the option.");
7157 AddWithoutInterpreting(*uninterpreted_option_,
options);
7163 return AddNameError(
"Option field \"" + debug_msg_name +
7164 "\" is not a field or extension of message \"" +
7169 dest_path.push_back(
field->number());
7171 if (i < uninterpreted_option_->name_size() - 1) {
7173 return AddNameError(
"Option \"" + debug_msg_name +
7174 "\" is an atomic type, not a message.");
7175 }
else if (
field->is_repeated()) {
7176 return AddNameError(
"Option field \"" + debug_msg_name +
7177 "\" is a repeated message. Repeated message "
7178 "options must be initialized using an "
7179 "aggregate value.");
7182 intermediate_fields.push_back(
field);
7197 if (!
field->is_repeated() &&
7198 !ExamineIfOptionIsSet(
7199 intermediate_fields.begin(), intermediate_fields.end(),
field,
7207 std::unique_ptr<UnknownFieldSet> unknown_fields(
new UnknownFieldSet());
7208 if (!SetOptionValue(
field, unknown_fields.get())) {
7214 for (std::vector<const FieldDescriptor*>::reverse_iterator
iter =
7215 intermediate_fields.rbegin();
7216 iter != intermediate_fields.rend(); ++
iter) {
7217 std::unique_ptr<UnknownFieldSet> parent_unknown_fields(
7219 switch ((*iter)->type()) {
7222 parent_unknown_fields->AddLengthDelimited((*iter)->number()));
7226 <<
"Unexpected failure while serializing option submessage "
7227 << debug_msg_name <<
"\".";
7232 parent_unknown_fields->AddGroup((*iter)->number())
7233 ->MergeFrom(*unknown_fields);
7242 unknown_fields.reset(parent_unknown_fields.release());
7247 options->GetReflection()->MutableUnknownFields(
options)->MergeFrom(
7251 if (
field->is_repeated()) {
7252 int index = repeated_option_counts_[dest_path]++;
7253 dest_path.push_back(
index);
7255 interpreted_paths_[src_path] = dest_path;
7262 if (interpreted_paths_.empty()) {
7277 RepeatedPtrField<SourceCodeInfo_Location>* locs = info->
mutable_location();
7278 RepeatedPtrField<SourceCodeInfo_Location> new_locs;
7279 bool copying =
false;
7281 std::vector<int> pathv;
7282 bool matched =
false;
7285 loc != locs->end();
loc++) {
7288 bool loc_matches =
true;
7289 if (
loc->path_size() <
static_cast<int64_t>(pathv.size())) {
7290 loc_matches =
false;
7292 for (
size_t j = 0;
j < pathv.size();
j++) {
7293 if (
loc->path(j) != pathv[j]) {
7294 loc_matches =
false;
7309 for (
int j = 0;
j <
loc->path_size();
j++) {
7310 pathv.push_back(
loc->path(j));
7313 std::map<std::vector<int>, std::vector<int>>
::iterator entry =
7314 interpreted_paths_.find(pathv);
7316 if (entry == interpreted_paths_.end()) {
7319 *new_locs.Add() = *
loc;
7329 new_locs.Reserve(locs->size());
7333 *new_locs.Add() = *
it;
7339 *replacement = *
loc;
7342 rit != entry->second.end(); rit++) {
7356 options->GetDescriptor()->FindFieldByName(
"uninterpreted_option");
7361 ->CopyFrom(uninterpreted_option);
7365 std::vector<const FieldDescriptor*>::const_iterator
7366 intermediate_fields_iter,
7367 std::vector<const FieldDescriptor*>::const_iterator intermediate_fields_end,
7374 if (intermediate_fields_iter == intermediate_fields_end) {
7376 for (
int i = 0;
i < unknown_fields.field_count();
i++) {
7377 if (unknown_fields.field(i).number() == innermost_field->number()) {
7378 return AddNameError(
"Option \"" + debug_msg_name +
7379 "\" was already set.");
7385 for (
int i = 0;
i < unknown_fields.field_count();
i++) {
7386 if (unknown_fields.field(i).number() ==
7387 (*intermediate_fields_iter)->number()) {
7388 const UnknownField* unknown_field = &unknown_fields.field(i);
7395 if (intermediate_unknown_fields.ParseFromString(
7396 unknown_field->length_delimited()) &&
7397 !ExamineIfOptionIsSet(intermediate_fields_iter + 1,
7398 intermediate_fields_end, innermost_field,
7400 intermediate_unknown_fields)) {
7408 if (!ExamineIfOptionIsSet(intermediate_fields_iter + 1,
7409 intermediate_fields_end, innermost_field,
7410 debug_msg_name, unknown_field->group())) {
7428 switch (option_field->cpp_type()) {
7430 if (uninterpreted_option_->has_positive_int_value()) {
7431 if (uninterpreted_option_->positive_int_value() >
7433 return AddValueError(
"Value out of range for int32 option \"" +
7434 option_field->full_name() +
"\".");
7436 SetInt32(option_field->number(),
7437 uninterpreted_option_->positive_int_value(),
7438 option_field->type(), unknown_fields);
7440 }
else if (uninterpreted_option_->has_negative_int_value()) {
7441 if (uninterpreted_option_->negative_int_value() <
7443 return AddValueError(
"Value out of range for int32 option \"" +
7444 option_field->full_name() +
"\".");
7446 SetInt32(option_field->number(),
7447 uninterpreted_option_->negative_int_value(),
7448 option_field->type(), unknown_fields);
7451 return AddValueError(
"Value must be integer for int32 option \"" +
7452 option_field->full_name() +
"\".");
7457 if (uninterpreted_option_->has_positive_int_value()) {
7458 if (uninterpreted_option_->positive_int_value() >
7460 return AddValueError(
"Value out of range for int64 option \"" +
7461 option_field->full_name() +
"\".");
7463 SetInt64(option_field->number(),
7464 uninterpreted_option_->positive_int_value(),
7465 option_field->type(), unknown_fields);
7467 }
else if (uninterpreted_option_->has_negative_int_value()) {
7468 SetInt64(option_field->number(),
7469 uninterpreted_option_->negative_int_value(),
7470 option_field->type(), unknown_fields);
7472 return AddValueError(
"Value must be integer for int64 option \"" +
7473 option_field->full_name() +
"\".");
7478 if (uninterpreted_option_->has_positive_int_value()) {
7479 if (uninterpreted_option_->positive_int_value() >
7481 return AddValueError(
"Value out of range for uint32 option \"" +
7482 option_field->name() +
"\".");
7484 SetUInt32(option_field->number(),
7485 uninterpreted_option_->positive_int_value(),
7486 option_field->type(), unknown_fields);
7489 return AddValueError(
7490 "Value must be non-negative integer for uint32 "
7492 option_field->full_name() +
"\".");
7497 if (uninterpreted_option_->has_positive_int_value()) {
7498 SetUInt64(option_field->number(),
7499 uninterpreted_option_->positive_int_value(),
7500 option_field->type(), unknown_fields);
7502 return AddValueError(
7503 "Value must be non-negative integer for uint64 "
7505 option_field->full_name() +
"\".");
7511 if (uninterpreted_option_->has_double_value()) {
7512 value = uninterpreted_option_->double_value();
7513 }
else if (uninterpreted_option_->has_positive_int_value()) {
7514 value = uninterpreted_option_->positive_int_value();
7515 }
else if (uninterpreted_option_->has_negative_int_value()) {
7516 value = uninterpreted_option_->negative_int_value();
7518 return AddValueError(
"Value must be number for float option \"" +
7519 option_field->full_name() +
"\".");
7521 unknown_fields->AddFixed32(option_field->number(),
7528 if (uninterpreted_option_->has_double_value()) {
7529 value = uninterpreted_option_->double_value();
7530 }
else if (uninterpreted_option_->has_positive_int_value()) {
7531 value = uninterpreted_option_->positive_int_value();
7532 }
else if (uninterpreted_option_->has_negative_int_value()) {
7533 value = uninterpreted_option_->negative_int_value();
7535 return AddValueError(
"Value must be number for double option \"" +
7536 option_field->full_name() +
"\".");
7538 unknown_fields->AddFixed64(option_field->number(),
7545 if (!uninterpreted_option_->has_identifier_value()) {
7546 return AddValueError(
7547 "Value must be identifier for boolean option "
7549 option_field->full_name() +
"\".");
7551 if (uninterpreted_option_->identifier_value() ==
"true") {
7553 }
else if (uninterpreted_option_->identifier_value() ==
"false") {
7556 return AddValueError(
7557 "Value must be \"true\" or \"false\" for boolean "
7559 option_field->full_name() +
"\".");
7561 unknown_fields->AddVarint(option_field->number(),
value);
7565 if (!uninterpreted_option_->has_identifier_value()) {
7566 return AddValueError(
7567 "Value must be identifier for enum-valued option "
7569 option_field->full_name() +
"\".");
7572 const std::string& value_name = uninterpreted_option_->identifier_value();
7579 fully_qualified_name.resize(fully_qualified_name.size() -
7581 fully_qualified_name += value_name;
7588 builder_->FindSymbolNotEnforcingDeps(fully_qualified_name);
7589 if (
auto* candicate_descriptor = symbol.enum_value_descriptor()) {
7590 if (candicate_descriptor->type() !=
enum_type) {
7591 return AddValueError(
7592 "Enum type \"" +
enum_type->full_name() +
7593 "\" has no value named \"" + value_name +
"\" for option \"" +
7594 option_field->full_name() +
7595 "\". This appears to be a value from a sibling type.");
7597 enum_value = candicate_descriptor;
7603 enum_value =
enum_type->FindValueByName(value_name);
7606 if (enum_value ==
nullptr) {
7607 return AddValueError(
"Enum type \"" +
7608 option_field->enum_type()->full_name() +
7609 "\" has no value named \"" + value_name +
7612 option_field->full_name() +
"\".");
7616 unknown_fields->AddVarint(
7617 option_field->number(),
7624 if (!uninterpreted_option_->has_string_value()) {
7625 return AddValueError(
7626 "Value must be quoted string for string option "
7628 option_field->full_name() +
"\".");
7631 unknown_fields->AddLengthDelimited(option_field->number(),
7632 uninterpreted_option_->string_value());
7636 if (!SetAggregateOption(option_field, unknown_fields)) {
7645 class DescriptorBuilder::OptionInterpreter::AggregateOptionFinder
7646 :
public TextFormat::Finder {
7658 return builder_->FindSymbol(
name).descriptor();
7666 builder_->LookupSymbolNoPlaceholder(
name,
descriptor->full_name());
7670 descriptor->options().message_set_wire_format()) {
7682 extension->message_type() == foreign_type) {
7718 if (!uninterpreted_option_->has_aggregate_value()) {
7719 return AddValueError(
"Option \"" + option_field->full_name() +
7720 "\" is a message. To set the entire message, use "
7722 option_field->name() +
7723 " = { <proto text format> }\". "
7724 "To set fields within it, use "
7726 option_field->name() +
".foo = value\".");
7730 std::unique_ptr<Message>
dynamic(dynamic_factory_.GetPrototype(
type)->New());
7732 <<
"Could not create an instance of " << option_field->DebugString();
7734 AggregateErrorCollector collector;
7735 AggregateOptionFinder finder;
7736 finder.builder_ = builder_;
7737 TextFormat::Parser
parser;
7738 parser.RecordErrorsTo(&collector);
7739 parser.SetFinder(&finder);
7740 if (!
parser.ParseFromString(uninterpreted_option_->aggregate_value(),
7742 AddValueError(
"Error while parsing option value for \"" +
7743 option_field->name() +
"\": " + collector.error_);
7747 dynamic->SerializeToString(&serial);
7749 unknown_fields->AddLengthDelimited(option_field->number(), serial);
7753 group->ParseFromString(serial);
7764 unknown_fields->AddVarint(
7773 unknown_fields->AddVarint(
7796 unknown_fields->AddVarint(
7850 for (std::set<const FileDescriptor*>::const_iterator
it =
7853 std::string error_message =
"Import " + (*it)->name() +
" is unused.";
7866 bool expecting_enum)
const {
7867 (void)expecting_enum;
7869 if (!lookup_name.empty() && lookup_name[0] ==
'.') {
7870 lookup_name = lookup_name.substr(1);
7887 type_descriptor_.message_type =
result.descriptor();
7894 if (lazy_default_value_enum_name_) {
7899 std::string::size_type last_dot =
name.find_last_of(
'.');
7900 if (last_dot != std::string::npos) {
7901 name =
name.substr(0, last_dot) +
"." + lazy_default_value_enum_name_;
7903 name = lazy_default_value_enum_name_;
7905 Symbol
result =
file()->pool()->CrossLinkOnDemandHelper(
name,
true);
7906 default_value_enum_ =
result.enum_value_descriptor();
7908 default_value_enum_ =
nullptr;
7910 if (!default_value_enum_) {
7914 default_value_enum_ =
enum_type->value(0);
7920 to_init->InternalTypeOnceInit();
7930 return type_ == TYPE_MESSAGE ||
type_ == TYPE_GROUP
7931 ? type_descriptor_.message_type
7939 return type_ == TYPE_ENUM ? type_descriptor_.enum_type :
nullptr;
7946 return default_value_enum_;
7950 const bool is_message_set_extension =
7955 return is_message_set_extension ?
message_type()->full_name() : full_name();
7960 auto*
names = dependencies_once_->dependencies_names;
7961 for (
int i = 0;
i < dependency_count();
i++) {
7969 to_init->InternalDependenciesOnceInit();
7973 if (dependencies_once_) {
7983 return input_type_.Get(
service());
7987 return output_type_.Get(
service());
8006 lazy_name_ =
file->pool_->tables_->Strdup(
name);
8015 file->pool_->CrossLinkOnDemandHelper(lazy_name_,
false).descriptor();
8025 #include <google/protobuf/port_undef.inc>