PROTOBUF_SYNC_PIPER
pull/7925/head
Joshua Haberman 4 years ago
parent de371235c9
commit b70695dd68
  1. 2
      csharp/src/Google.Protobuf/Google.Protobuf.csproj
  2. 2
      java/pom.xml
  3. 6
      objectivec/DevTools/full_mac_build.sh
  4. 8
      objectivec/ProtocolBuffers_iOS.xcodeproj/project.pbxproj
  5. 2
      objectivec/Tests/GPBTestUtilities.m
  6. 7
      python/google/protobuf/internal/api_implementation.py
  7. 4
      python/google/protobuf/text_format.py
  8. 88
      src/google/protobuf/arena.cc
  9. 24
      src/google/protobuf/arena.h
  10. 454
      src/google/protobuf/arena_impl.h
  11. 1
      src/google/protobuf/arena_unittest.cc
  12. 24
      src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc
  13. 25
      src/google/protobuf/compiler/csharp/csharp_doc_comment.cc
  14. 7
      src/google/protobuf/compiler/csharp/csharp_enum.cc
  15. 12
      src/google/protobuf/compiler/csharp/csharp_field_base.cc
  16. 7
      src/google/protobuf/compiler/csharp/csharp_field_base.h
  17. 14
      src/google/protobuf/compiler/csharp/csharp_generator.cc
  18. 4
      src/google/protobuf/compiler/csharp/csharp_generator.h
  19. 19
      src/google/protobuf/compiler/csharp/csharp_helpers.cc
  20. 2
      src/google/protobuf/compiler/csharp/csharp_helpers.h
  21. 10
      src/google/protobuf/compiler/csharp/csharp_message.cc
  22. 16
      src/google/protobuf/compiler/csharp/csharp_names.h
  23. 5
      src/google/protobuf/compiler/java/java_enum.cc
  24. 5
      src/google/protobuf/compiler/java/java_enum_lite.cc
  25. 5
      src/google/protobuf/compiler/java/java_file.cc
  26. 10
      src/google/protobuf/compiler/objectivec/objectivec_enum.cc
  27. 4
      src/google/protobuf/compiler/objectivec/objectivec_enum.h
  28. 8
      src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc
  29. 3
      src/google/protobuf/compiler/objectivec/objectivec_enum_field.h
  30. 20
      src/google/protobuf/compiler/objectivec/objectivec_extension.cc
  31. 8
      src/google/protobuf/compiler/objectivec/objectivec_extension.h
  32. 18
      src/google/protobuf/compiler/objectivec/objectivec_field.cc
  33. 19
      src/google/protobuf/compiler/objectivec/objectivec_field.h
  34. 23
      src/google/protobuf/compiler/objectivec/objectivec_file.cc
  35. 7
      src/google/protobuf/compiler/objectivec/objectivec_file.h
  36. 16
      src/google/protobuf/compiler/objectivec/objectivec_generator.cc
  37. 11
      src/google/protobuf/compiler/objectivec/objectivec_generator.h
  38. 388
      src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
  39. 149
      src/google/protobuf/compiler/objectivec/objectivec_helpers.h
  40. 40
      src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc
  41. 20
      src/google/protobuf/compiler/objectivec/objectivec_map_field.cc
  42. 6
      src/google/protobuf/compiler/objectivec/objectivec_map_field.h
  43. 31
      src/google/protobuf/compiler/objectivec/objectivec_message.cc
  44. 15
      src/google/protobuf/compiler/objectivec/objectivec_message.h
  45. 15
      src/google/protobuf/compiler/objectivec/objectivec_message_field.cc
  46. 12
      src/google/protobuf/compiler/objectivec/objectivec_message_field.h
  47. 10
      src/google/protobuf/compiler/objectivec/objectivec_oneof.cc
  48. 6
      src/google/protobuf/compiler/objectivec/objectivec_oneof.h
  49. 4
      src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc
  50. 162
      src/google/protobuf/compiler/php/php_generator.cc
  51. 8
      src/google/protobuf/compiler/php/php_generator.h
  52. 16
      src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc
  53. 3
      src/google/protobuf/descriptor.cc

@ -30,7 +30,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Memory" Version="4.5.2"/>
<PackageReference Include="System.Memory" Version="4.5.3"/>
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" Version="1.0.0"/>
<!-- Needed for the net45 build to work on Unix. See https://github.com/dotnet/designs/pull/33 -->
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" PrivateAssets="All" Version="1.0.0"/>

@ -75,7 +75,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<dependency>

@ -289,7 +289,7 @@ if [[ "${DO_XCODE_IOS_TESTS}" == "yes" ]] ; then
-disable-concurrent-destination-testing
)
;;
11.*)
11.* | 12.*)
# Dropped 32bit as Apple doesn't seem support the simulators either.
XCODEBUILD_TEST_BASE_IOS+=(
-destination "platform=iOS Simulator,name=iPhone 8,OS=latest" # 64bit
@ -352,10 +352,8 @@ if [[ "${DO_XCODE_TVOS_TESTS}" == "yes" ]] ; then
echo "ERROR: Xcode 10.0 or higher is required to build the test suite." 1>&2
exit 11
;;
10.* | 11.* )
10.* | 11.* | 12.*)
XCODEBUILD_TEST_BASE_TVOS+=(
# Test on the oldest and current.
-destination "platform=tvOS Simulator,name=Apple TV,OS=11.0"
-destination "platform=tvOS Simulator,name=Apple TV 4K,OS=latest"
)
;;

@ -856,13 +856,11 @@
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
ENABLE_BITCODE = YES;
FRAMEWORK_SEARCH_PATHS = (
"\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"",
"$(inherited)",
);
INFOPLIST_FILE = "Tests/UnitTests-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
@ -889,13 +887,11 @@
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
ENABLE_BITCODE = YES;
FRAMEWORK_SEARCH_PATHS = (
"\"$(DEVELOPER_LIBRARY_DIR)/Frameworks\"",
"$(inherited)",
);
INFOPLIST_FILE = "Tests/UnitTests-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
@ -972,7 +968,7 @@
GCC_WARN_UNUSED_PARAMETER = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
GENERATE_PROFILING_CODE = NO;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
ONLY_ACTIVE_ARCH = YES;
RUN_CLANG_STATIC_ANALYZER = YES;
SDKROOT = iphoneos;
@ -1041,7 +1037,7 @@
GCC_WARN_UNUSED_PARAMETER = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
GENERATE_PROFILING_CODE = NO;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
RUN_CLANG_STATIC_ANALYZER = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";

@ -779,7 +779,7 @@ const uint32_t kGPBDefaultRepeatCount = 2;
[message.repeatedSfixed64Array addValue:210 + i * 100];
[message.repeatedFloatArray addValue:211 + i * 100];
[message.repeatedDoubleArray addValue:212 + i * 100];
[message.repeatedBoolArray addValue:(i % 2)];
[message.repeatedBoolArray addValue:(BOOL)(i % 2)];
NSString *string = [[NSString alloc] initWithFormat:@"%d", 215 + i * 100];
[message.repeatedStringArray addObject:string];
[string release];

@ -60,11 +60,16 @@ if _api_version < 0: # Still unspecified?
raise ImportError('_use_fast_cpp_protos import succeeded but was None')
del _use_fast_cpp_protos
_api_version = 2
# Can not import both use_fast_cpp_protos and use_pure_python.
from google.protobuf import use_pure_python
raise RuntimeError(
'Conflict depend on both use_fast_cpp_protos and use_pure_python')
except ImportError:
try:
# pylint: disable=g-import-not-at-top
from google.protobuf.internal import use_pure_python
from google.protobuf import use_pure_python
del use_pure_python # Avoids a pylint error and namespace pollution.
_api_version = 0
except ImportError:
# TODO(b/74017912): It's unsafe to enable :use_fast_cpp_protos by default;
# it can cause data loss if you have any Python-only extensions to any

@ -882,9 +882,11 @@ class _Parser(object):
raise tokenizer.ParseErrorPreviousToken('Expected "%s".' %
(expanded_any_end_token,))
self._MergeField(tokenizer, expanded_any_sub_message)
deterministic = False
message.Pack(expanded_any_sub_message,
type_url_prefix=type_url_prefix,
deterministic=True)
deterministic=deterministic)
return
if tokenizer.TryConsume('['):

@ -53,10 +53,6 @@ PROTOBUF_EXPORT /*static*/ void* (*const ArenaOptions::kDefaultBlockAlloc)(
namespace internal {
const size_t ArenaImpl::kBlockHeaderSize;
const size_t ArenaImpl::kSerialArenaSize;
const size_t ArenaImpl::kOptionsSize;
ArenaImpl::CacheAlignedLifecycleIdGenerator ArenaImpl::lifecycle_id_generator_;
#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
@ -108,7 +104,8 @@ ArenaImpl::ArenaImpl(const ArenaOptions& options) {
// Create the special block.
const bool special = true;
const bool user_owned = (mem == options.initial_block);
auto block = new (mem) Block(mem_size, nullptr, special, user_owned);
auto block =
new (mem) SerialArena::Block(mem_size, nullptr, special, user_owned);
// Options occupy the beginning of the initial block.
options_ = new (block->Pointer(block->pos())) Options;
@ -152,7 +149,7 @@ void ArenaImpl::Init(bool record_allocs) {
space_allocated_.store(0, std::memory_order_relaxed);
}
void ArenaImpl::SetInitialBlock(Block* block) {
void ArenaImpl::SetInitialBlock(SerialArena::Block* block) {
// Calling thread owns the first block. This allows the single-threaded case
// to allocate on the first block without having to perform atomic operations.
SerialArena* serial = SerialArena::New(block, &thread_cache(), this);
@ -174,7 +171,7 @@ ArenaImpl::~ArenaImpl() {
deallocator = options_->block_dealloc;
}
PerBlock([deallocator](Block* b) {
PerBlock([deallocator](SerialArena::Block* b) {
#ifdef ADDRESS_SANITIZER
// This memory was provided by the underlying allocator as unpoisoned, so
// return it in an unpoisoned state.
@ -201,25 +198,26 @@ uint64 ArenaImpl::Reset() {
// Discard all blocks except the special block (if present).
uint64 space_allocated = 0;
Block* special_block = nullptr;
SerialArena::Block* special_block = nullptr;
auto deallocator = (options_ ? options_->block_dealloc : &ArenaFree);
PerBlock([&space_allocated, &special_block, deallocator](Block* b) {
space_allocated += b->size();
PerBlock(
[&space_allocated, &special_block, deallocator](SerialArena::Block* b) {
space_allocated += b->size();
#ifdef ADDRESS_SANITIZER
// This memory was provided by the underlying allocator as unpoisoned, so
// return it in an unpoisoned state.
ASAN_UNPOISON_MEMORY_REGION(b->Pointer(0), b->size());
// This memory was provided by the underlying allocator as unpoisoned,
// so return it in an unpoisoned state.
ASAN_UNPOISON_MEMORY_REGION(b->Pointer(0), b->size());
#endif // ADDRESS_SANITIZER
if (!b->special()) {
(*deallocator)(b, b->size());
} else {
// Prepare special block for reuse.
// Note: if options_ is present, it occupies the beginning of the
// block and therefore pos is advanced past it.
GOOGLE_DCHECK(special_block == nullptr);
special_block = b;
}
});
if (!b->special()) {
(*deallocator)(b, b->size());
} else {
// Prepare special block for reuse.
// Note: if options_ is present, it occupies the beginning of the
// block and therefore pos is advanced past it.
GOOGLE_DCHECK(special_block == nullptr);
special_block = b;
}
});
Init(record_allocs());
if (special_block != nullptr) {
@ -233,12 +231,13 @@ uint64 ArenaImpl::Reset() {
return space_allocated;
}
ArenaImpl::Block* ArenaImpl::NewBlock(Block* last_block, size_t min_bytes) {
std::pair<void*, size_t> ArenaImpl::NewBuffer(size_t last_size,
size_t min_bytes) {
size_t size;
if (last_block) {
if (last_size != -1) {
// Double the current block size, up to a limit.
auto max_size = options_ ? options_->max_block_size : kDefaultMaxBlockSize;
size = std::min(2 * last_block->size(), max_size);
size = std::min(2 * last_size, max_size);
} else {
size = options_ ? options_->start_block_size : kDefaultStartBlockSize;
}
@ -247,14 +246,22 @@ ArenaImpl::Block* ArenaImpl::NewBlock(Block* last_block, size_t min_bytes) {
size = std::max(size, kBlockHeaderSize + min_bytes);
void* mem = options_ ? (*options_->block_alloc)(size) : ::operator new(size);
Block* b = new (mem) Block(size, last_block, false, false);
space_allocated_.fetch_add(size, std::memory_order_relaxed);
return {mem, size};
}
SerialArena::Block* SerialArena::NewBlock(SerialArena::Block* last_block,
size_t min_bytes, ArenaImpl* arena) {
void* mem;
size_t size;
std::tie(mem, size) =
arena->NewBuffer(last_block ? last_block->size() : -1, min_bytes);
Block* b = new (mem) Block(size, last_block, false, false);
return b;
}
PROTOBUF_NOINLINE
void ArenaImpl::SerialArena::AddCleanupFallback(void* elem,
void (*cleanup)(void*)) {
void SerialArena::AddCleanupFallback(void* elem, void (*cleanup)(void*)) {
size_t size = cleanup_ ? cleanup_->size * 2 : kMinCleanupListElements;
size = std::min(size, kMaxCleanupListElements);
size_t bytes = internal::AlignUpTo8(CleanupChunk::SizeOf(size));
@ -306,11 +313,11 @@ void ArenaImpl::AddCleanupFallback(void* elem, void (*cleanup)(void*)) {
}
PROTOBUF_NOINLINE
void* ArenaImpl::SerialArena::AllocateAlignedFallback(size_t n) {
void* SerialArena::AllocateAlignedFallback(size_t n) {
// Sync back to current's pos.
head_->set_pos(head_->size() - (limit_ - ptr_));
head_ = arena_->NewBlock(head_, n);
head_ = NewBlock(head_, n, arena_);
ptr_ = head_->Pointer(head_->pos());
limit_ = head_->Pointer(head_->size());
@ -338,7 +345,7 @@ uint64 ArenaImpl::SpaceUsed() const {
return space_used;
}
uint64 ArenaImpl::SerialArena::SpaceUsed() const {
uint64 SerialArena::SpaceUsed() const {
// Get current block's size from ptr_ (since we can't trust head_->pos().
uint64 space_used = ptr_ - head_->Pointer(kBlockHeaderSize);
// Get subsequent block size from b->pos().
@ -346,7 +353,7 @@ uint64 ArenaImpl::SerialArena::SpaceUsed() const {
space_used += (b->pos() - kBlockHeaderSize);
}
// Remove the overhead of the SerialArena itself.
space_used -= kSerialArenaSize;
space_used -= ArenaImpl::kSerialArenaSize;
return space_used;
}
@ -360,13 +367,13 @@ void ArenaImpl::CleanupList() {
}
}
void ArenaImpl::SerialArena::CleanupList() {
void SerialArena::CleanupList() {
if (cleanup_ != NULL) {
CleanupListFallback();
}
}
void ArenaImpl::SerialArena::CleanupListFallback() {
void SerialArena::CleanupListFallback() {
// The first chunk might be only partially full, so calculate its size
// from cleanup_ptr_. Subsequent chunks are always full, so use list->size.
size_t n = cleanup_ptr_ - &cleanup_->nodes[0];
@ -386,12 +393,11 @@ void ArenaImpl::SerialArena::CleanupListFallback() {
}
}
ArenaImpl::SerialArena* ArenaImpl::SerialArena::New(Block* b, void* owner,
ArenaImpl* arena) {
SerialArena* SerialArena::New(Block* b, void* owner, ArenaImpl* arena) {
auto pos = b->pos();
GOOGLE_DCHECK_LE(pos + kSerialArenaSize, b->size());
GOOGLE_DCHECK_LE(pos + ArenaImpl::kSerialArenaSize, b->size());
SerialArena* serial = reinterpret_cast<SerialArena*>(b->Pointer(pos));
b->set_pos(pos + kSerialArenaSize);
b->set_pos(pos + ArenaImpl::kSerialArenaSize);
serial->arena_ = arena;
serial->owner_ = owner;
serial->head_ = b;
@ -404,7 +410,7 @@ ArenaImpl::SerialArena* ArenaImpl::SerialArena::New(Block* b, void* owner,
}
PROTOBUF_NOINLINE
ArenaImpl::SerialArena* ArenaImpl::GetSerialArenaFallback(void* me) {
SerialArena* ArenaImpl::GetSerialArenaFallback(void* me) {
// Look for this SerialArena in our linked list.
SerialArena* serial = threads_.load(std::memory_order_acquire);
for (; serial; serial = serial->next()) {
@ -416,7 +422,7 @@ ArenaImpl::SerialArena* ArenaImpl::GetSerialArenaFallback(void* me) {
if (!serial) {
// This thread doesn't have any SerialArena, which also means it doesn't
// have any blocks yet. So we'll allocate its first block now.
Block* b = NewBlock(NULL, kSerialArenaSize);
SerialArena::Block* b = SerialArena::NewBlock(NULL, kSerialArenaSize, this);
serial = SerialArena::New(b, me, this);
SerialArena* head = threads_.load(std::memory_order_relaxed);

@ -486,15 +486,23 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final {
// when allocation recording is enabled.
template <typename T>
PROTOBUF_ALWAYS_INLINE void* AllocateInternal(bool skip_explicit_ownership) {
static_assert(alignof(T) <= 8, "T is overaligned, see b/151247138");
const size_t n = internal::AlignUpTo8(sizeof(T));
impl_.RecordAlloc(RTTI_TYPE_ID(T), n);
// Monitor allocation if needed.
impl_.RecordAlloc(RTTI_TYPE_ID(T), n);
if (skip_explicit_ownership) {
return AllocateAlignedNoHook(n);
return AllocateAlignedTo<alignof(T)>(sizeof(T));
} else {
return impl_.AllocateAlignedAndAddCleanup(
n, &internal::arena_destruct_object<T>);
if (alignof(T) <= 8) {
return impl_.AllocateAlignedAndAddCleanup(
n, &internal::arena_destruct_object<T>);
} else {
auto ptr =
reinterpret_cast<uintptr_t>(impl_.AllocateAlignedAndAddCleanup(
sizeof(T) + alignof(T) - 8,
&internal::arena_destruct_object<T>));
return reinterpret_cast<void*>((ptr + alignof(T) - 8) &
(~alignof(T) + 1));
}
}
}
@ -549,10 +557,12 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final {
PROTOBUF_ALWAYS_INLINE T* CreateInternalRawArray(size_t num_elements) {
GOOGLE_CHECK_LE(num_elements, std::numeric_limits<size_t>::max() / sizeof(T))
<< "Requested size is too large to fit into size_t.";
// We count on compiler to realize that if sizeof(T) is a multiple of
// 8 AlignUpTo can be elided.
const size_t n = internal::AlignUpTo8(sizeof(T) * num_elements);
// Monitor allocation if needed.
impl_.RecordAlloc(RTTI_TYPE_ID(T), n);
return static_cast<T*>(AllocateAlignedNoHook(n));
return static_cast<T*>(AllocateAlignedTo<alignof(T)>(n));
}
template <typename T, typename... Args>
@ -655,7 +665,7 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final {
// TODO(b/151247138): if the pointer would have been aligned already,
// this is wasting space. We should pass the alignment down.
uintptr_t ptr = reinterpret_cast<uintptr_t>(AllocateAligned(n + Align - 8));
ptr = (ptr + Align - 1) & -Align;
ptr = (ptr + Align - 1) & (~Align + 1);
return reinterpret_cast<void*>(ptr);
}

@ -90,6 +90,164 @@ class PROTOBUF_EXPORT ArenaMetricsCollector {
uint64 alloc_size) = 0;
};
class ArenaImpl;
// A thread-unsafe Arena that can only be used within its owning thread.
class PROTOBUF_EXPORT SerialArena {
public:
// Blocks are variable length malloc-ed objects. The following structure
// describes the common header for all blocks.
class PROTOBUF_EXPORT Block {
public:
Block(size_t size, Block* next, bool special, bool user_owned)
: next_and_bits_(reinterpret_cast<uintptr_t>(next) | (special ? 1 : 0) |
(user_owned ? 2 : 0)),
pos_(kBlockHeaderSize),
size_(size) {
GOOGLE_DCHECK_EQ(reinterpret_cast<uintptr_t>(next) & 3, 0u);
}
char* Pointer(size_t n) {
GOOGLE_DCHECK(n <= size_);
return reinterpret_cast<char*>(this) + n;
}
// One of the blocks may be special. This is either a user-supplied
// initial block, or a block we created at startup to hold Options info.
// A special block is not deleted by Reset.
bool special() const { return (next_and_bits_ & 1) != 0; }
// Whether or not this current block is owned by the user.
// Only special blocks can be user_owned.
bool user_owned() const { return (next_and_bits_ & 2) != 0; }
Block* next() const {
const uintptr_t bottom_bits = 3;
return reinterpret_cast<Block*>(next_and_bits_ & ~bottom_bits);
}
void clear_next() {
next_and_bits_ &= 3; // Set next to nullptr, preserve bottom bits.
}
size_t pos() const { return pos_; }
size_t size() const { return size_; }
void set_pos(size_t pos) { pos_ = pos; }
private:
// Holds pointer to next block for this thread + special/user_owned bits.
uintptr_t next_and_bits_;
size_t pos_;
size_t size_;
// data follows
};
// The allocate/free methods here are a little strange, since SerialArena is
// allocated inside a Block which it also manages. This is to avoid doing
// an extra allocation for the SerialArena itself.
// Creates a new SerialArena inside Block* and returns it.
static SerialArena* New(Block* b, void* owner, ArenaImpl* arena);
void CleanupList();
uint64 SpaceUsed() const;
bool HasSpace(size_t n) { return n <= static_cast<size_t>(limit_ - ptr_); }
void* AllocateAligned(size_t n) {
GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned.
GOOGLE_DCHECK_GE(limit_, ptr_);
if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) {
return AllocateAlignedFallback(n);
}
void* ret = ptr_;
ptr_ += n;
#ifdef ADDRESS_SANITIZER
ASAN_UNPOISON_MEMORY_REGION(ret, n);
#endif // ADDRESS_SANITIZER
return ret;
}
// Allocate space if the current region provides enough space.
bool MaybeAllocateAligned(size_t n, void** out) {
GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned.
GOOGLE_DCHECK_GE(limit_, ptr_);
if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) return false;
void* ret = ptr_;
ptr_ += n;
#ifdef ADDRESS_SANITIZER
ASAN_UNPOISON_MEMORY_REGION(ret, n);
#endif // ADDRESS_SANITIZER
*out = ret;
return true;
}
void AddCleanup(void* elem, void (*cleanup)(void*)) {
if (PROTOBUF_PREDICT_FALSE(cleanup_ptr_ == cleanup_limit_)) {
AddCleanupFallback(elem, cleanup);
return;
}
cleanup_ptr_->elem = elem;
cleanup_ptr_->cleanup = cleanup;
cleanup_ptr_++;
}
void* AllocateAlignedAndAddCleanup(size_t n, void (*cleanup)(void*)) {
void* ret = AllocateAligned(n);
AddCleanup(ret, cleanup);
return ret;
}
Block* head() const { return head_; }
void* owner() const { return owner_; }
SerialArena* next() const { return next_; }
void set_next(SerialArena* next) { next_ = next; }
static Block* NewBlock(Block* last_block, size_t min_bytes, ArenaImpl* arena);
private:
// Node contains the ptr of the object to be cleaned up and the associated
// cleanup function ptr.
struct CleanupNode {
void* elem; // Pointer to the object to be cleaned up.
void (*cleanup)(void*); // Function pointer to the destructor or deleter.
};
// Cleanup uses a chunked linked list, to reduce pointer chasing.
struct CleanupChunk {
static size_t SizeOf(size_t i) {
return sizeof(CleanupChunk) + (sizeof(CleanupNode) * (i - 1));
}
size_t size; // Total elements in the list.
CleanupChunk* next; // Next node in the list.
CleanupNode nodes[1]; // True length is |size|.
};
ArenaImpl* arena_; // Containing arena.
void* owner_; // &ThreadCache of this thread;
Block* head_; // Head of linked list of blocks.
CleanupChunk* cleanup_; // Head of cleanup list.
SerialArena* next_; // Next SerialArena in this linked list.
// Next pointer to allocate from. Always 8-byte aligned. Points inside
// head_ (and head_->pos will always be non-canonical). We keep these
// here to reduce indirection.
char* ptr_;
char* limit_;
// Next CleanupList members to append to. These point inside cleanup_.
CleanupNode* cleanup_ptr_;
CleanupNode* cleanup_limit_;
void* AllocateAlignedFallback(size_t n);
void AddCleanupFallback(void* elem, void (*cleanup)(void*));
void CleanupListFallback();
public:
static constexpr size_t kBlockHeaderSize =
(sizeof(Block) + 7) & static_cast<size_t>(-8);
};
// This class provides the core Arena memory allocation library. Different
// implementations only need to implement the public interface below.
// Arena is not a template type as that would only be useful if all protos
@ -109,7 +267,7 @@ class PROTOBUF_EXPORT ArenaImpl {
// Ignore initial block if it is too small.
if (mem != nullptr && size >= kBlockHeaderSize + kSerialArenaSize) {
SetInitialBlock(new (mem) Block(size, nullptr, true, true));
SetInitialBlock(new (mem) SerialArena::Block(size, nullptr, true, true));
}
}
@ -160,165 +318,17 @@ class PROTOBUF_EXPORT ArenaImpl {
}
}
private:
friend class ArenaBenchmark;
void* AllocateAlignedFallback(size_t n);
void* AllocateAlignedAndAddCleanupFallback(size_t n, void (*cleanup)(void*));
void AddCleanupFallback(void* elem, void (*cleanup)(void*));
// Node contains the ptr of the object to be cleaned up and the associated
// cleanup function ptr.
struct CleanupNode {
void* elem; // Pointer to the object to be cleaned up.
void (*cleanup)(void*); // Function pointer to the destructor or deleter.
};
// Cleanup uses a chunked linked list, to reduce pointer chasing.
struct CleanupChunk {
static size_t SizeOf(size_t i) {
return sizeof(CleanupChunk) + (sizeof(CleanupNode) * (i - 1));
}
size_t size; // Total elements in the list.
CleanupChunk* next; // Next node in the list.
CleanupNode nodes[1]; // True length is |size|.
};
class Block;
// A thread-unsafe Arena that can only be used within its owning thread.
class PROTOBUF_EXPORT SerialArena {
public:
// The allocate/free methods here are a little strange, since SerialArena is
// allocated inside a Block which it also manages. This is to avoid doing
// an extra allocation for the SerialArena itself.
// Creates a new SerialArena inside Block* and returns it.
static SerialArena* New(Block* b, void* owner, ArenaImpl* arena);
void CleanupList();
uint64 SpaceUsed() const;
bool HasSpace(size_t n) { return n <= static_cast<size_t>(limit_ - ptr_); }
void* AllocateAligned(size_t n) {
GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned.
GOOGLE_DCHECK_GE(limit_, ptr_);
if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) {
return AllocateAlignedFallback(n);
}
void* ret = ptr_;
ptr_ += n;
#ifdef ADDRESS_SANITIZER
ASAN_UNPOISON_MEMORY_REGION(ret, n);
#endif // ADDRESS_SANITIZER
return ret;
}
// Allocate space if the current region provides enough space.
bool MaybeAllocateAligned(size_t n, void** out) {
GOOGLE_DCHECK_EQ(internal::AlignUpTo8(n), n); // Must be already aligned.
GOOGLE_DCHECK_GE(limit_, ptr_);
if (PROTOBUF_PREDICT_FALSE(!HasSpace(n))) return false;
void* ret = ptr_;
ptr_ += n;
#ifdef ADDRESS_SANITIZER
ASAN_UNPOISON_MEMORY_REGION(ret, n);
#endif // ADDRESS_SANITIZER
*out = ret;
return true;
}
void AddCleanup(void* elem, void (*cleanup)(void*)) {
if (PROTOBUF_PREDICT_FALSE(cleanup_ptr_ == cleanup_limit_)) {
AddCleanupFallback(elem, cleanup);
return;
}
cleanup_ptr_->elem = elem;
cleanup_ptr_->cleanup = cleanup;
cleanup_ptr_++;
}
void* AllocateAlignedAndAddCleanup(size_t n, void (*cleanup)(void*)) {
void* ret = AllocateAligned(n);
AddCleanup(ret, cleanup);
return ret;
}
Block* head() const { return head_; }
void* owner() const { return owner_; }
SerialArena* next() const { return next_; }
void set_next(SerialArena* next) { next_ = next; }
private:
void* AllocateAlignedFallback(size_t n);
void AddCleanupFallback(void* elem, void (*cleanup)(void*));
void CleanupListFallback();
ArenaImpl* arena_; // Containing arena.
void* owner_; // &ThreadCache of this thread;
Block* head_; // Head of linked list of blocks.
CleanupChunk* cleanup_; // Head of cleanup list.
SerialArena* next_; // Next SerialArena in this linked list.
// Next pointer to allocate from. Always 8-byte aligned. Points inside
// head_ (and head_->pos will always be non-canonical). We keep these
// here to reduce indirection.
char* ptr_;
char* limit_;
// Next CleanupList members to append to. These point inside cleanup_.
CleanupNode* cleanup_ptr_;
CleanupNode* cleanup_limit_;
};
// Blocks are variable length malloc-ed objects. The following structure
// describes the common header for all blocks.
class PROTOBUF_EXPORT Block {
public:
Block(size_t size, Block* next, bool special, bool user_owned)
: next_and_bits_(reinterpret_cast<uintptr_t>(next) | (special ? 1 : 0) |
(user_owned ? 2 : 0)),
pos_(kBlockHeaderSize),
size_(size) {
GOOGLE_DCHECK_EQ(reinterpret_cast<uintptr_t>(next) & 3, 0u);
}
char* Pointer(size_t n) {
GOOGLE_DCHECK(n <= size_);
return reinterpret_cast<char*>(this) + n;
}
// One of the blocks may be special. This is either a user-supplied
// initial block, or a block we created at startup to hold Options info.
// A special block is not deleted by Reset.
bool special() const { return (next_and_bits_ & 1) != 0; }
std::pair<void*, size_t> NewBuffer(size_t last_size, size_t min_bytes);
// Whether or not this current block is owned by the user.
// Only special blocks can be user_owned.
bool user_owned() const { return (next_and_bits_ & 2) != 0; }
Block* next() const {
const uintptr_t bottom_bits = 3;
return reinterpret_cast<Block*>(next_and_bits_ & ~bottom_bits);
}
void clear_next() {
next_and_bits_ &= 3; // Set next to nullptr, preserve bottom bits.
}
size_t pos() const { return pos_; }
size_t size() const { return size_; }
void set_pos(size_t pos) { pos_ = pos; }
private:
// Holds pointer to next block for this thread + special/user_owned bits.
uintptr_t next_and_bits_;
private:
// Pointer to a linked list of SerialArena.
std::atomic<SerialArena*> threads_;
std::atomic<SerialArena*> hint_; // Fast thread-local block access
std::atomic<size_t> space_allocated_; // Total size of all allocated blocks.
size_t pos_;
size_t size_;
// data follows
};
// Unique for each arena. Changes on Reset().
// Least-significant-bit is 1 iff allocations should be recorded.
uint64 lifecycle_id_;
struct Options {
size_t start_block_size;
@ -328,59 +338,15 @@ class PROTOBUF_EXPORT ArenaImpl {
ArenaMetricsCollector* metrics_collector;
};
#ifdef _MSC_VER
#pragma warning(disable:4324)
#endif
struct alignas(64) ThreadCache {
#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
// If we are using the ThreadLocalStorage class to store the ThreadCache,
// then the ThreadCache's default constructor has to be responsible for
// initializing it.
ThreadCache()
: next_lifecycle_id(0),
last_lifecycle_id_seen(-1),
last_serial_arena(NULL) {}
#endif
Options* options_ = nullptr;
// Number of per-thread lifecycle IDs to reserve. Must be power of two.
// To reduce contention on a global atomic, each thread reserves a batch of
// IDs. The following number is caluculated based on a stress test with
// ~6500 threads all frequently allocating a new arena.
static constexpr size_t kPerThreadIds = 256;
// Next lifecycle ID available to this thread. We need to reserve a new
// batch, if `next_lifecycle_id & (kPerThreadIds - 1) == 0`.
uint64 next_lifecycle_id;
// The ThreadCache is considered valid as long as this matches the
// lifecycle_id of the arena being used.
uint64 last_lifecycle_id_seen;
SerialArena* last_serial_arena;
};
// Lifecycle_id can be highly contended variable in a situation of lots of
// arena creation. Make sure that other global variables are not sharing the
// cacheline.
#ifdef _MSC_VER
#pragma warning(disable:4324)
#endif
struct alignas(64) CacheAlignedLifecycleIdGenerator {
std::atomic<LifecycleIdAtomic> id;
};
static CacheAlignedLifecycleIdGenerator lifecycle_id_generator_;
#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
// Android ndk does not support __thread keyword so we use a custom thread
// local storage class we implemented.
// iOS also does not support the __thread keyword.
static ThreadCache& thread_cache();
#elif defined(PROTOBUF_USE_DLLS)
// Thread local variables cannot be exposed through DLL interface but we can
// wrap them in static functions.
static ThreadCache& thread_cache();
#else
static PROTOBUF_THREAD_LOCAL ThreadCache thread_cache_;
static ThreadCache& thread_cache() { return thread_cache_; }
#endif
void* AllocateAlignedFallback(size_t n);
void* AllocateAlignedAndAddCleanupFallback(size_t n, void (*cleanup)(void*));
void AddCleanupFallback(void* elem, void (*cleanup)(void*));
void Init(bool record_allocs);
void SetInitialBlock(Block* block); // Can be called right after Init()
void SetInitialBlock(
SerialArena::Block* block); // Can be called right after Init()
// Return true iff allocations should be recorded in a metrics collector.
inline bool record_allocs() const { return lifecycle_id_ & 1; }
@ -395,8 +361,8 @@ class PROTOBUF_EXPORT ArenaImpl {
// fn() may delete blocks and arenas, so fetch next pointers before fn();
SerialArena* cur = serial;
serial = serial->next();
for (Block* block = cur->head(); block != nullptr;) {
Block* b = block;
for (auto* block = cur->head(); block != nullptr;) {
auto* b = block;
block = b->next();
fn(b);
}
@ -416,13 +382,6 @@ class PROTOBUF_EXPORT ArenaImpl {
hint_.store(serial, std::memory_order_release);
}
std::atomic<SerialArena*>
threads_; // Pointer to a linked list of SerialArena.
std::atomic<SerialArena*> hint_; // Fast thread-local block access
std::atomic<size_t> space_allocated_; // Total size of all allocated blocks.
Block* NewBlock(Block* last_block, size_t min_bytes);
PROTOBUF_ALWAYS_INLINE bool GetSerialArenaFast(SerialArena** arena) {
if (GetSerialArenaFromThreadCache(arena)) return true;
@ -451,11 +410,57 @@ class PROTOBUF_EXPORT ArenaImpl {
}
SerialArena* GetSerialArenaFallback(void* me);
// Unique for each arena. Changes on Reset().
// Least-significant-bit is 1 iff allocations should be recorded.
uint64 lifecycle_id_;
#ifdef _MSC_VER
#pragma warning(disable : 4324)
#endif
struct alignas(64) ThreadCache {
#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
// If we are using the ThreadLocalStorage class to store the ThreadCache,
// then the ThreadCache's default constructor has to be responsible for
// initializing it.
ThreadCache()
: next_lifecycle_id(0),
last_lifecycle_id_seen(-1),
last_serial_arena(NULL) {}
#endif
Options* options_ = nullptr;
// Number of per-thread lifecycle IDs to reserve. Must be power of two.
// To reduce contention on a global atomic, each thread reserves a batch of
// IDs. The following number is caluculated based on a stress test with
// ~6500 threads all frequently allocating a new arena.
static constexpr size_t kPerThreadIds = 256;
// Next lifecycle ID available to this thread. We need to reserve a new
// batch, if `next_lifecycle_id & (kPerThreadIds - 1) == 0`.
uint64 next_lifecycle_id;
// The ThreadCache is considered valid as long as this matches the
// lifecycle_id of the arena being used.
uint64 last_lifecycle_id_seen;
SerialArena* last_serial_arena;
};
// Lifecycle_id can be highly contended variable in a situation of lots of
// arena creation. Make sure that other global variables are not sharing the
// cacheline.
#ifdef _MSC_VER
#pragma warning(disable : 4324)
#endif
struct alignas(64) CacheAlignedLifecycleIdGenerator {
std::atomic<LifecycleIdAtomic> id;
};
static CacheAlignedLifecycleIdGenerator lifecycle_id_generator_;
#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
// Android ndk does not support __thread keyword so we use a custom thread
// local storage class we implemented.
// iOS also does not support the __thread keyword.
static ThreadCache& thread_cache();
#elif defined(PROTOBUF_USE_DLLS)
// Thread local variables cannot be exposed through DLL interface but we can
// wrap them in static functions.
static ThreadCache& thread_cache();
#else
static PROTOBUF_THREAD_LOCAL ThreadCache thread_cache_;
static ThreadCache& thread_cache() { return thread_cache_; }
#endif
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArenaImpl);
// All protos have pointers back to the arena hence Arena must have
@ -466,11 +471,10 @@ class PROTOBUF_EXPORT ArenaImpl {
public:
// kBlockHeaderSize is sizeof(Block), aligned up to the nearest multiple of 8
// to protect the invariant that pos is always at a multiple of 8.
static const size_t kBlockHeaderSize =
(sizeof(Block) + 7) & static_cast<size_t>(-8);
static const size_t kSerialArenaSize =
static constexpr size_t kBlockHeaderSize = SerialArena::kBlockHeaderSize;
static constexpr size_t kSerialArenaSize =
(sizeof(SerialArena) + 7) & static_cast<size_t>(-8);
static const size_t kOptionsSize =
static constexpr size_t kOptionsSize =
(sizeof(Options) + 7) & static_cast<size_t>(-8);
static_assert(kBlockHeaderSize % 8 == 0,
"kBlockHeaderSize must be a multiple of 8.");

@ -31,6 +31,7 @@
#include <google/protobuf/arena.h>
#include <algorithm>
#include <cstddef>
#include <cstring>
#include <memory>
#include <string>

@ -65,11 +65,11 @@ class MockErrorCollector : public MultiFileErrorCollector {
MockErrorCollector() {}
~MockErrorCollector() {}
string text_;
std::string text_;
// implements ErrorCollector ---------------------------------------
void AddError(const string& filename, int line, int column,
const string& message) {
void AddError(const std::string& filename, int line, int column,
const std::string& message) {
strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n",
filename, line, column, message);
}
@ -77,14 +77,14 @@ class MockErrorCollector : public MultiFileErrorCollector {
class MockGeneratorContext : public GeneratorContext {
public:
void ExpectFileMatches(const string& virtual_filename,
const string& physical_filename) {
void ExpectFileMatches(const std::string& virtual_filename,
const std::string& physical_filename) {
auto it = files_.find(virtual_filename);
ASSERT_TRUE(it != files_.end())
<< "Generator failed to generate file: " << virtual_filename;
string expected_contents = *it->second;
std::string expected_contents = *it->second;
string actual_contents;
std::string actual_contents;
GOOGLE_CHECK_OK(
File::GetContentsAsText(TestSourceDir() + "/" + physical_filename,
&actual_contents, true))
@ -97,7 +97,7 @@ class MockGeneratorContext : public GeneratorContext {
// implements GeneratorContext --------------------------------------
virtual io::ZeroCopyOutputStream* Open(const string& filename) {
virtual io::ZeroCopyOutputStream* Open(const std::string& filename) {
auto& map_slot = files_[filename];
map_slot.reset(new std::string);
return new io::StringOutputStream(map_slot.get());
@ -110,7 +110,7 @@ class MockGeneratorContext : public GeneratorContext {
class GenerateAndTest {
public:
GenerateAndTest() {}
void Run(const FileDescriptor* proto_file, string file1, string file2) {
void Run(const FileDescriptor* proto_file, std::string file1, std::string file2) {
ASSERT_TRUE(proto_file != NULL) << TestSourceDir();
ASSERT_TRUE(generator_.Generate(proto_file, parameter_,
&context_, &error_));
@ -123,14 +123,14 @@ class GenerateAndTest {
private:
Generator generator_;
MockGeneratorContext context_;
string error_;
string parameter_;
std::string error_;
std::string parameter_;
};
TEST(CsharpBootstrapTest, GeneratedCsharpDescriptorMatches) {
// Skip this whole test if the csharp directory doesn't exist (i.e., a C++11
// only distribution).
string descriptor_file_name =
std::string descriptor_file_name =
"../csharp/src/Google.Protobuf/Reflection/Descriptor.cs";
if (!File::Exists(TestSourceDir() + "/" + descriptor_file_name)) {
return;

@ -47,7 +47,7 @@ namespace csharp {
// is inlined in the relevant code. If more control is required, that code can be moved here.
void WriteDocCommentBodyImpl(io::Printer* printer, SourceLocation location) {
string comments = location.leading_comments.empty() ?
std::string comments = location.leading_comments.empty() ?
location.trailing_comments : location.leading_comments;
if (comments.empty()) {
return;
@ -56,7 +56,7 @@ void WriteDocCommentBodyImpl(io::Printer* printer, SourceLocation location) {
// node of a summary element, not part of an attribute.
comments = StringReplace(comments, "&", "&amp;", true);
comments = StringReplace(comments, "<", "&lt;", true);
std::vector<string> lines;
std::vector<std::string> lines;
lines = Split(comments, "\n", false);
// TODO: We really should work out which part to put in the summary and which to put in the remarks...
// but that needs to be part of a bigger effort to understand the markdown better anyway.
@ -66,17 +66,18 @@ void WriteDocCommentBodyImpl(io::Printer* printer, SourceLocation location) {
// to preserve the blank lines themselves, as this is relevant in the markdown.
// Note that we can't remove leading or trailing whitespace as *that's* relevant in markdown too.
// (We don't skip "just whitespace" lines, either.)
for (std::vector<string>::iterator it = lines.begin(); it != lines.end(); ++it) {
string line = *it;
if (line.empty()) {
last_was_empty = true;
} else {
if (last_was_empty) {
printer->Print("///\n");
}
last_was_empty = false;
printer->Print("///$line$\n", "line", *it);
for (std::vector<std::string>::iterator it = lines.begin();
it != lines.end(); ++it) {
std::string line = *it;
if (line.empty()) {
last_was_empty = true;
} else {
if (last_was_empty) {
printer->Print("///\n");
}
last_was_empty = false;
printer->Print("///$line$\n", "line", *it);
}
}
printer->Print("/// </summary>\n");
}

@ -61,12 +61,13 @@ void EnumGenerator::Generate(io::Printer* printer) {
"access_level", class_access_level(),
"name", descriptor_->name());
printer->Indent();
std::set<string> used_names;
std::set<std::string> used_names;
std::set<int> used_number;
for (int i = 0; i < descriptor_->value_count(); i++) {
WriteEnumValueDocComment(printer, descriptor_->value(i));
string original_name = descriptor_->value(i)->name();
string name = GetEnumValueName(descriptor_->name(), descriptor_->value(i)->name());
std::string original_name = descriptor_->value(i)->name();
std::string name =
GetEnumValueName(descriptor_->name(), descriptor_->value(i)->name());
// Make sure we don't get any duplicate names due to prefix removal.
while (!used_names.insert(name).second) {
// It's possible we'll end up giving this warning multiple times, but that's better than not at all.

@ -51,7 +51,7 @@ namespace compiler {
namespace csharp {
void FieldGeneratorBase::SetCommonFieldVariables(
std::map<string, string>* variables) {
std::map<std::string, std::string>* variables) {
// Note: this will be valid even though the tag emitted for packed and unpacked versions of
// repeated fields varies by wire format. The wire format is encoded in the bottom 3 bits, which
// never effects the tag size.
@ -63,7 +63,7 @@ void FieldGeneratorBase::SetCommonFieldVariables(
uint tag = internal::WireFormat::MakeTag(descriptor_);
uint8 tag_array[5];
io::CodedOutputStream::WriteTagToArray(tag, tag_array);
string tag_bytes = StrCat(tag_array[0]);
std::string tag_bytes = StrCat(tag_array[0]);
for (int i = 1; i < part_tag_size; i++) {
tag_bytes += ", " + StrCat(tag_array[i]);
}
@ -108,8 +108,8 @@ void FieldGeneratorBase::SetCommonFieldVariables(
(*variables)["has_not_property_check"] = "!" + (*variables)["has_property_check"];
(*variables)["other_has_not_property_check"] = "!" + (*variables)["other_has_property_check"];
if (presenceIndex_ != -1) {
string hasBitsNumber = StrCat(presenceIndex_ / 32);
string hasBitsMask = StrCat(1 << (presenceIndex_ % 32));
std::string hasBitsNumber = StrCat(presenceIndex_ / 32);
std::string hasBitsMask = StrCat(1 << (presenceIndex_ % 32));
(*variables)["has_field_check"] = "(_hasBits" + hasBitsNumber + " & " + hasBitsMask + ") != 0";
(*variables)["set_has_field"] = "_hasBits" + hasBitsNumber + " |= " + hasBitsMask;
(*variables)["clear_has_field"] = "_hasBits" + hasBitsNumber + " &= ~" + hasBitsMask;
@ -123,7 +123,7 @@ void FieldGeneratorBase::SetCommonFieldVariables(
}
void FieldGeneratorBase::SetCommonOneofFieldVariables(
std::map<string, string>* variables) {
std::map<std::string, std::string>* variables) {
(*variables)["oneof_name"] = oneof_name();
if (SupportsPresenceApi(descriptor_)) {
(*variables)["has_property_check"] = "Has" + property_name();
@ -216,7 +216,7 @@ std::string FieldGeneratorBase::type_name(const FieldDescriptor* descriptor) {
if (IsWrapperType(descriptor)) {
const FieldDescriptor* wrapped_field =
descriptor->message_type()->field(0);
string wrapped_field_type_name = type_name(wrapped_field);
std::string wrapped_field_type_name = type_name(wrapped_field);
// String and ByteString go to the same type; other wrapped types
// go to the nullable equivalent.
if (wrapped_field->type() == FieldDescriptor::TYPE_STRING ||

@ -74,14 +74,15 @@ class FieldGeneratorBase : public SourceGeneratorBase {
protected:
const FieldDescriptor* descriptor_;
const int presenceIndex_;
std::map<string, string> variables_;
std::map<std::string, std::string> variables_;
void AddDeprecatedFlag(io::Printer* printer);
void AddNullCheck(io::Printer* printer);
void AddNullCheck(io::Printer* printer, const std::string& name);
void AddPublicMemberAttributes(io::Printer* printer);
void SetCommonOneofFieldVariables(std::map<string, string>* variables);
void SetCommonOneofFieldVariables(
std::map<std::string, std::string>* variables);
std::string oneof_property_name();
std::string oneof_name();
@ -96,7 +97,7 @@ class FieldGeneratorBase : public SourceGeneratorBase {
std::string capitalized_type_name();
private:
void SetCommonFieldVariables(std::map<string, string>* variables);
void SetCommonFieldVariables(std::map<std::string, std::string>* variables);
std::string GetStringDefaultValueInternal(const FieldDescriptor* descriptor);
std::string GetBytesDefaultValueInternal(const FieldDescriptor* descriptor);
};

@ -61,13 +61,11 @@ void GenerateFile(const FileDescriptor* file, io::Printer* printer,
reflectionClassGenerator.Generate(printer);
}
bool Generator::Generate(
const FileDescriptor* file,
const string& parameter,
GeneratorContext* generator_context,
string* error) const {
std::vector<std::pair<string, string> > options;
bool Generator::Generate(const FileDescriptor* file,
const std::string& parameter,
GeneratorContext* generator_context,
std::string* error) const {
std::vector<std::pair<std::string, std::string> > options;
ParseGeneratorParameter(parameter, &options);
struct Options cli_options;
@ -88,7 +86,7 @@ bool Generator::Generate(
}
}
string filename_error = "";
std::string filename_error = "";
std::string filename = GetOutputFile(file,
cli_options.file_extension,
cli_options.base_namespace_specified,

@ -54,9 +54,9 @@ class PROTOC_EXPORT Generator : public CodeGenerator {
~Generator();
bool Generate(
const FileDescriptor* file,
const string& parameter,
const std::string& parameter,
GeneratorContext* generator_context,
string* error) const override;
std::string* error) const override;
uint64_t GetSupportedFeatures() const override;
};

@ -143,7 +143,7 @@ std::string GetExtensionClassUnqualifiedName(const FileDescriptor* descriptor) {
std::string UnderscoresToCamelCase(const std::string& input,
bool cap_next_letter,
bool preserve_period) {
string result;
std::string result;
// Note: I distrust ctype.h due to locales.
for (int i = 0; i < input.size(); i++) {
if ('a' <= input[i] && input[i] <= 'z') {
@ -195,7 +195,7 @@ std::string UnderscoresToPascalCase(const std::string& input) {
// Lower letter Alphanumeric Same as current
// Upper letter Alphanumeric Lower
std::string ShoutyToPascalCase(const std::string& input) {
string result;
std::string result;
// Simple way of implementing "always start with upper"
char previous = '_';
for (int i = 0; i < input.size(); i++) {
@ -325,7 +325,7 @@ std::string ToCSharpName(const std::string& name, const FileDescriptor* file) {
if (!result.empty()) {
result += '.';
}
string classname;
std::string classname;
if (file->package().empty()) {
classname = name;
} else {
@ -396,19 +396,20 @@ std::string GetPropertyName(const FieldDescriptor* descriptor) {
std::string GetOutputFile(const FileDescriptor* descriptor,
const std::string file_extension,
const bool generate_directories,
const std::string base_namespace, string* error) {
string relative_filename = GetFileNameBase(descriptor) + file_extension;
const std::string base_namespace,
std::string* error) {
std::string relative_filename = GetFileNameBase(descriptor) + file_extension;
if (!generate_directories) {
return relative_filename;
}
string ns = GetFileNamespace(descriptor);
string namespace_suffix = ns;
std::string ns = GetFileNamespace(descriptor);
std::string namespace_suffix = ns;
if (!base_namespace.empty()) {
// Check that the base_namespace is either equal to or a leading part of
// the file namespace. This isn't just a simple prefix; "Foo.B" shouldn't
// be regarded as a prefix of "Foo.Bar". The simplest option is to add "."
// to both.
string extended_ns = ns + ".";
std::string extended_ns = ns + ".";
if (extended_ns.find(base_namespace + ".") != 0) {
*error = "Namespace " + ns + " is not a prefix namespace of base namespace " + base_namespace;
return ""; // This will be ignored, because we've set an error.
@ -419,7 +420,7 @@ std::string GetOutputFile(const FileDescriptor* descriptor,
}
}
string namespace_dir = StringReplace(namespace_suffix, ".", "/", true);
std::string namespace_dir = StringReplace(namespace_suffix, ".", "/", true);
if (!namespace_dir.empty()) {
namespace_dir += "/";
}

@ -138,7 +138,7 @@ inline bool IsDescriptorOptionMessage(const Descriptor* descriptor) {
if (!IsDescriptorProto(descriptor->file())) {
return false;
}
const string name = descriptor->full_name();
const std::string name = descriptor->full_name();
return name == "google.protobuf.FileOptions" ||
name == "google.protobuf.MessageOptions" ||
name == "google.protobuf.FieldOptions" ||

@ -112,7 +112,7 @@ void MessageGenerator::AddSerializableAttribute(io::Printer* printer) {
}
void MessageGenerator::Generate(io::Printer* printer) {
std::map<string, string> vars;
std::map<std::string, std::string> vars;
vars["class_name"] = class_name();
vars["access_level"] = class_access_level();
@ -374,7 +374,7 @@ bool MessageGenerator::HasNestedGeneratedTypes()
}
void MessageGenerator::GenerateCloningCode(io::Printer* printer) {
std::map<string, string> vars;
std::map<std::string, std::string> vars;
WriteGeneratedCodeAttributes(printer);
vars["class_name"] = class_name();
printer->Print(
@ -438,7 +438,7 @@ void MessageGenerator::GenerateFreezingCode(io::Printer* printer) {
}
void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) {
std::map<string, string> vars;
std::map<std::string, std::string> vars;
vars["class_name"] = class_name();
// Equality
@ -605,7 +605,7 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) {
// Note: These are separate from GenerateMessageSerializationMethods()
// because they need to be generated even for messages that are optimized
// for code size.
std::map<string, string> vars;
std::map<std::string, std::string> vars;
vars["class_name"] = class_name();
WriteGeneratedCodeAttributes(printer);
@ -685,7 +685,7 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) {
}
void MessageGenerator::GenerateMainParseLoop(io::Printer* printer, bool use_parse_context) {
std::map<string, string> vars;
std::map<std::string, std::string> vars;
vars["maybe_ref_input"] = use_parse_context ? "ref input" : "input";
printer->Print(

@ -60,14 +60,14 @@ namespace csharp {
//
// Returns:
// The namespace to use for given file descriptor.
string PROTOC_EXPORT GetFileNamespace(const FileDescriptor* descriptor);
std::string PROTOC_EXPORT GetFileNamespace(const FileDescriptor* descriptor);
// Requires:
// descriptor != NULL
//
// Returns:
// The fully-qualified C# class name.
string PROTOC_EXPORT GetClassName(const Descriptor* descriptor);
std::string PROTOC_EXPORT GetClassName(const Descriptor* descriptor);
// Requires:
// descriptor != NULL
@ -76,7 +76,8 @@ string PROTOC_EXPORT GetClassName(const Descriptor* descriptor);
// The fully-qualified name of the C# class that provides
// access to the file descriptor. Proto compiler generates
// such class for each .proto file processed.
string PROTOC_EXPORT GetReflectionClassName(const FileDescriptor* descriptor);
std::string PROTOC_EXPORT
GetReflectionClassName(const FileDescriptor* descriptor);
// Generates output file name for given file descriptor. If generate_directories
// is true, the output file will be put under directory corresponding to file's
@ -92,10 +93,11 @@ string PROTOC_EXPORT GetReflectionClassName(const FileDescriptor* descriptor);
// The file name to use as output file for given file descriptor. In case
// of failure, this function will return empty string and error parameter
// will contain the error message.
string PROTOC_EXPORT GetOutputFile(const FileDescriptor* descriptor,
const string file_extension,
const bool generate_directories,
const string base_namespace, string* error);
std::string PROTOC_EXPORT GetOutputFile(const FileDescriptor* descriptor,
const std::string file_extension,
const bool generate_directories,
const std::string base_namespace,
std::string* error);
} // namespace csharp
} // namespace compiler

@ -77,9 +77,10 @@ void EnumGenerator::Generate(io::Printer* printer) {
WriteEnumDocComment(printer, descriptor_);
MaybePrintGeneratedAnnotation(context_, printer, descriptor_, immutable_api_);
printer->Print(
"public enum $classname$\n"
"$deprecation$public enum $classname$\n"
" implements com.google.protobuf.ProtocolMessageEnum {\n",
"classname", descriptor_->name());
"classname", descriptor_->name(), "deprecation",
descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "");
printer->Annotate("classname", descriptor_);
printer->Indent();

@ -78,9 +78,10 @@ void EnumLiteGenerator::Generate(io::Printer* printer) {
WriteEnumDocComment(printer, descriptor_);
MaybePrintGeneratedAnnotation(context_, printer, descriptor_, immutable_api_);
printer->Print(
"public enum $classname$\n"
"$deprecation$public enum $classname$\n"
" implements com.google.protobuf.Internal.EnumLite {\n",
"classname", descriptor_->name());
"classname", descriptor_->name(), "deprecation",
descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "");
printer->Annotate("classname", descriptor_);
printer->Indent();

@ -76,7 +76,6 @@ struct FieldDescriptorCompare {
typedef std::set<const FieldDescriptor*, FieldDescriptorCompare>
FieldDescriptorSet;
// Recursively searches the given message to collect extensions.
// Returns true if all the extensions can be recognized. The extensions will be
// appended in to the extensions parameter.
@ -86,9 +85,7 @@ bool CollectExtensions(const Message& message, FieldDescriptorSet* extensions) {
const Reflection* reflection = message.GetReflection();
// There are unknown fields that could be extensions, thus this call fails.
UnknownFieldSet unknown_fields;
unknown_fields.MergeFrom(reflection->GetUnknownFields(message));
if (unknown_fields.field_count() > 0) return false;
if (reflection->GetUnknownFields(message).field_count() > 0) return false;
std::vector<const FieldDescriptor*> fields;
reflection->ListFields(message, &fields);

@ -65,7 +65,7 @@ EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor)
base_values_.push_back(value);
value_names.insert(EnumValueName(value));
} else {
string value_name(EnumValueName(value));
std::string value_name(EnumValueName(value));
if (value_names.find(value_name) != value_names.end()) {
alias_values_to_skip_.insert(value);
} else {
@ -79,7 +79,7 @@ EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor)
EnumGenerator::~EnumGenerator() {}
void EnumGenerator::GenerateHeader(io::Printer* printer) {
string enum_comments;
std::string enum_comments;
SourceLocation location;
if (descriptor_->GetSourceLocation(&location)) {
enum_comments = BuildCommentsString(location, true);
@ -129,7 +129,7 @@ void EnumGenerator::GenerateHeader(io::Printer* printer) {
}
SourceLocation location;
if (all_values_[i]->GetSourceLocation(&location)) {
string comments = BuildCommentsString(location, true).c_str();
std::string comments = BuildCommentsString(location, true).c_str();
if (comments.length() > 0) {
if (i > 0) {
printer->Print("\n");
@ -172,11 +172,11 @@ void EnumGenerator::GenerateSource(io::Printer* printer) {
// will be zero.
TextFormatDecodeData text_format_decode_data;
int enum_value_description_key = -1;
string text_blob;
std::string text_blob;
for (int i = 0; i < all_values_.size(); i++) {
++enum_value_description_key;
string short_name(EnumValueShortName(all_values_[i]));
std::string short_name(EnumValueShortName(all_values_[i]));
text_blob += short_name + '\0';
if (UnCamelCaseEnumShortName(short_name) != all_values_[i]->name()) {
text_format_decode_data.AddString(enum_value_description_key, short_name,

@ -53,14 +53,14 @@ class EnumGenerator {
void GenerateHeader(io::Printer* printer);
void GenerateSource(io::Printer* printer);
const string& name() const { return name_; }
const std::string& name() const { return name_; }
private:
const EnumDescriptor* descriptor_;
std::vector<const EnumValueDescriptor*> base_values_;
std::vector<const EnumValueDescriptor*> all_values_;
std::set<const EnumValueDescriptor*> alias_values_to_skip_;
const string name_;
const std::string name_;
};
} // namespace objectivec

@ -44,8 +44,8 @@ namespace objectivec {
namespace {
void SetEnumVariables(const FieldDescriptor* descriptor,
std::map<string, string>* variables) {
string type = EnumName(descriptor->enum_type());
std::map<std::string, std::string>* variables) {
std::string type = EnumName(descriptor->enum_type());
(*variables)["storage_type"] = type;
// For non repeated fields, if it was defined in a different file, the
// property decls need to use "enum NAME" rather than just "NAME" to support
@ -116,14 +116,14 @@ void EnumFieldGenerator::GenerateCFunctionImplementations(
}
void EnumFieldGenerator::DetermineForwardDeclarations(
std::set<string>* fwd_decls) const {
std::set<std::string>* fwd_decls) const {
SingleFieldGenerator::DetermineForwardDeclarations(fwd_decls);
// If it is an enum defined in a different file, then we'll need a forward
// declaration for it. When it is in our file, all the enums are output
// before the message, so it will be declared before it is needed.
if (descriptor_->file() != descriptor_->enum_type()->file()) {
// Enum name is already in "storage_type".
const string& name = variable("storage_type");
const std::string& name = variable("storage_type");
fwd_decls->insert("GPB_ENUM_FWD_DECLARE(" + name + ")");
}
}

@ -50,7 +50,8 @@ class EnumFieldGenerator : public SingleFieldGenerator {
public:
virtual void GenerateCFunctionDeclarations(io::Printer* printer) const;
virtual void GenerateCFunctionImplementations(io::Printer* printer) const;
virtual void DetermineForwardDeclarations(std::set<string>* fwd_decls) const;
virtual void DetermineForwardDeclarations(
std::set<std::string>* fwd_decls) const;
protected:
EnumFieldGenerator(const FieldDescriptor* descriptor, const Options& options);

@ -41,7 +41,7 @@ namespace protobuf {
namespace compiler {
namespace objectivec {
ExtensionGenerator::ExtensionGenerator(const string& root_class_name,
ExtensionGenerator::ExtensionGenerator(const std::string& root_class_name,
const FieldDescriptor* descriptor)
: method_name_(ExtensionMethodName(descriptor)),
root_class_and_method_name_(root_class_name + "_" + method_name_),
@ -59,7 +59,7 @@ ExtensionGenerator::ExtensionGenerator(const string& root_class_name,
ExtensionGenerator::~ExtensionGenerator() {}
void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) {
std::map<string, string> vars;
std::map<std::string, std::string> vars;
vars["method_name"] = method_name_;
if (IsRetainedName(method_name_)) {
vars["storage_attribute"] = " NS_RETURNS_NOT_RETAINED";
@ -82,13 +82,13 @@ void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) {
void ExtensionGenerator::GenerateStaticVariablesInitialization(
io::Printer* printer) {
std::map<string, string> vars;
std::map<std::string, std::string> vars;
vars["root_class_and_method_name"] = root_class_and_method_name_;
const string containing_type = ClassName(descriptor_->containing_type());
const std::string containing_type = ClassName(descriptor_->containing_type());
vars["extended_type"] = ObjCClass(containing_type);
vars["number"] = StrCat(descriptor_->number());
std::vector<string> options;
std::vector<std::string> options;
if (descriptor_->is_repeated()) options.push_back("GPBExtensionRepeated");
if (descriptor_->is_packed()) options.push_back("GPBExtensionPacked");
if (descriptor_->containing_type()->options().message_set_wire_format()) {
@ -110,8 +110,8 @@ void ExtensionGenerator::GenerateStaticVariablesInitialization(
} else {
vars["default"] = DefaultValue(descriptor_);
}
string type = GetCapitalizedType(descriptor_);
vars["extension_type"] = string("GPBDataType") + type;
std::string type = GetCapitalizedType(descriptor_);
vars["extension_type"] = std::string("GPBDataType") + type;
if (objc_type == OBJECTIVECTYPE_ENUM) {
vars["enum_desc_func_name"] =
@ -134,12 +134,12 @@ void ExtensionGenerator::GenerateStaticVariablesInitialization(
}
void ExtensionGenerator::DetermineObjectiveCClassDefinitions(
std::set<string>* fwd_decls) {
string extended_type = ClassName(descriptor_->containing_type());
std::set<std::string>* fwd_decls) {
std::string extended_type = ClassName(descriptor_->containing_type());
fwd_decls->insert(ObjCClassDeclaration(extended_type));
ObjectiveCType objc_type = GetObjectiveCType(descriptor_);
if (objc_type == OBJECTIVECTYPE_MESSAGE) {
string message_type = ClassName(descriptor_->message_type());
std::string message_type = ClassName(descriptor_->message_type());
fwd_decls->insert(ObjCClassDeclaration(message_type));
}
}

@ -41,7 +41,7 @@ namespace objectivec {
class ExtensionGenerator {
public:
ExtensionGenerator(const string& root_class_name,
ExtensionGenerator(const std::string& root_class_name,
const FieldDescriptor* descriptor);
~ExtensionGenerator();
@ -51,11 +51,11 @@ class ExtensionGenerator {
void GenerateMembersHeader(io::Printer* printer);
void GenerateStaticVariablesInitialization(io::Printer* printer);
void GenerateRegistrationSource(io::Printer* printer);
void DetermineObjectiveCClassDefinitions(std::set<string>* fwd_decls);
void DetermineObjectiveCClassDefinitions(std::set<std::string>* fwd_decls);
private:
string method_name_;
string root_class_and_method_name_;
std::string method_name_;
std::string root_class_and_method_name_;
const FieldDescriptor* descriptor_;
};

@ -48,16 +48,16 @@ namespace objectivec {
namespace {
void SetCommonFieldVariables(const FieldDescriptor* descriptor,
std::map<string, string>* variables) {
string camel_case_name = FieldName(descriptor);
string raw_field_name;
std::map<std::string, std::string>* variables) {
std::string camel_case_name = FieldName(descriptor);
std::string raw_field_name;
if (descriptor->type() == FieldDescriptor::TYPE_GROUP) {
raw_field_name = descriptor->message_type()->name();
} else {
raw_field_name = descriptor->name();
}
// The logic here has to match -[GGPBFieldDescriptor textFormatName].
const string un_camel_case_name(
const std::string un_camel_case_name(
UnCamelCaseFieldName(camel_case_name, descriptor));
const bool needs_custom_name = (raw_field_name != un_camel_case_name);
@ -67,10 +67,10 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
} else {
(*variables)["comments"] = "\n";
}
const string& classname = ClassName(descriptor->containing_type());
const std::string& classname = ClassName(descriptor->containing_type());
(*variables)["classname"] = classname;
(*variables)["name"] = camel_case_name;
const string& capitalized_name = FieldNameCapitalized(descriptor);
const std::string& capitalized_name = FieldNameCapitalized(descriptor);
(*variables)["capitalized_name"] = capitalized_name;
(*variables)["raw_field_name"] = raw_field_name;
(*variables)["field_number_name"] =
@ -78,7 +78,7 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
(*variables)["field_number"] = StrCat(descriptor->number());
(*variables)["field_type"] = GetCapitalizedType(descriptor);
(*variables)["deprecated_attribute"] = GetOptionalDeprecatedAttribute(descriptor);
std::vector<string> field_flags;
std::vector<std::string> field_flags;
if (descriptor->is_repeated()) field_flags.push_back("GPBFieldRepeated");
if (descriptor->is_required()) field_flags.push_back("GPBFieldRequired");
if (descriptor->is_optional()) field_flags.push_back("GPBFieldOptional");
@ -185,12 +185,12 @@ void FieldGenerator::GenerateCFunctionImplementations(
}
void FieldGenerator::DetermineForwardDeclarations(
std::set<string>* fwd_decls) const {
std::set<std::string>* fwd_decls) const {
// Nothing
}
void FieldGenerator::DetermineObjectiveCClassDefinitions(
std::set<string>* fwd_decls) const {
std::set<std::string>* fwd_decls) const {
// Nothing
}

@ -65,8 +65,10 @@ class FieldGenerator {
virtual void GenerateCFunctionImplementations(io::Printer* printer) const;
// Exposed for subclasses, should always call it on the parent class also.
virtual void DetermineForwardDeclarations(std::set<string>* fwd_decls) const;
virtual void DetermineObjectiveCClassDefinitions(std::set<string>* fwd_decls) const;
virtual void DetermineForwardDeclarations(
std::set<std::string>* fwd_decls) const;
virtual void DetermineObjectiveCClassDefinitions(
std::set<std::string>* fwd_decls) const;
// Used during generation, not intended to be extended by subclasses.
void GenerateFieldDescription(
@ -81,16 +83,17 @@ class FieldGenerator {
virtual void SetExtraRuntimeHasBitsBase(int index_base);
void SetOneofIndexBase(int index_base);
string variable(const char* key) const {
std::string variable(const char* key) const {
return variables_.find(key)->second;
}
bool needs_textformat_name_support() const {
const string& field_flags = variable("fieldflags");
return field_flags.find("GPBFieldTextFormatNameCustom") != string::npos;
const std::string& field_flags = variable("fieldflags");
return field_flags.find("GPBFieldTextFormatNameCustom") !=
std::string::npos;
}
string generated_objc_name() const { return variable("name"); }
string raw_field_name() const { return variable("raw_field_name"); }
std::string generated_objc_name() const { return variable("name"); }
std::string raw_field_name() const { return variable("raw_field_name"); }
protected:
FieldGenerator(const FieldDescriptor* descriptor, const Options& options);
@ -99,7 +102,7 @@ class FieldGenerator {
bool WantsHasProperty(void) const;
const FieldDescriptor* descriptor_;
std::map<string, string> variables_;
std::map<std::string, std::string> variables_;
};
class SingleFieldGenerator : public FieldGenerator {

@ -209,7 +209,7 @@ FileGenerator::FileGenerator(const FileDescriptor *file, const Options& options)
FileGenerator::~FileGenerator() {}
void FileGenerator::GenerateHeader(io::Printer *printer) {
std::vector<string> headers;
std::vector<std::string> headers;
// Generated files bundled with the library get minimal imports, everything
// else gets the wrapper so everything is usable.
if (is_bundled_proto_) {
@ -244,7 +244,7 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
options_.named_framework_to_proto_path_mappings_path,
options_.runtime_import_prefix,
is_bundled_proto_);
const string header_extension(kHeaderExtension);
const std::string header_extension(kHeaderExtension);
for (int i = 0; i < file_->public_dependency_count(); i++) {
import_writer.AddFile(file_->public_dependency(i), header_extension);
}
@ -264,11 +264,11 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
"CF_EXTERN_C_BEGIN\n"
"\n");
std::set<string> fwd_decls;
std::set<std::string> fwd_decls;
for (const auto& generator : message_generators_) {
generator->DetermineForwardDeclarations(&fwd_decls);
}
for (std::set<string>::const_iterator i(fwd_decls.begin());
for (std::set<std::string>::const_iterator i(fwd_decls.begin());
i != fwd_decls.end(); ++i) {
printer->Print("$value$;\n", "value", *i);
}
@ -338,7 +338,7 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
void FileGenerator::GenerateSource(io::Printer *printer) {
// #import the runtime support.
std::vector<string> headers;
std::vector<std::string> headers;
headers.push_back("GPBProtocolBuffers_RuntimeSupport.h");
PrintFileRuntimePreamble(printer, headers);
@ -358,14 +358,14 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
options_.named_framework_to_proto_path_mappings_path,
options_.runtime_import_prefix,
is_bundled_proto_);
const string header_extension(kHeaderExtension);
const std::string header_extension(kHeaderExtension);
// #import the header for this proto file.
import_writer.AddFile(file_, header_extension);
// #import the headers for anything that a plain dependency of this proto
// file (that means they were just an include, not a "public" include).
std::set<string> public_import_names;
std::set<std::string> public_import_names;
for (int i = 0; i < file_->public_dependency_count(); i++) {
public_import_names.insert(file_->public_dependency(i)->name());
}
@ -400,7 +400,7 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
}
}
std::set<string> fwd_decls;
std::set<std::string> fwd_decls;
for (const auto& generator : message_generators_) {
generator->DetermineObjectiveCClassDefinitions(&fwd_decls);
}
@ -501,7 +501,7 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
for (std::vector<const FileDescriptor *>::iterator iter =
deps_with_extensions.begin();
iter != deps_with_extensions.end(); ++iter) {
const string root_class_name(FileClassName((*iter)));
const std::string root_class_name(FileClassName((*iter)));
printer->Print(
"[registry addExtensions:[$dependency$ extensionRegistry]];\n",
"dependency", root_class_name);
@ -531,7 +531,7 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
// File descriptor only needed if there are messages to use it.
if (!message_generators_.empty()) {
std::map<string, string> vars;
std::map<std::string, std::string> vars;
vars["root_class_name"] = root_class_name_;
vars["package"] = file_->package();
vars["objc_prefix"] = FileClassPrefix(file_);
@ -592,7 +592,8 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
// files. This currently only supports the runtime coming from a framework
// as defined by the official CocoaPod.
void FileGenerator::PrintFileRuntimePreamble(
io::Printer* printer, const std::vector<string>& headers_to_import) const {
io::Printer* printer,
const std::vector<std::string>& headers_to_import) const {
printer->Print(
"// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
"// source: $filename$\n"

@ -58,11 +58,11 @@ class FileGenerator {
void GenerateSource(io::Printer* printer);
void GenerateHeader(io::Printer* printer);
const string& RootClassName() const { return root_class_name_; }
const std::string& RootClassName() const { return root_class_name_; }
private:
const FileDescriptor* file_;
string root_class_name_;
std::string root_class_name_;
bool is_bundled_proto_;
std::vector<std::unique_ptr<EnumGenerator>> enum_generators_;
@ -72,7 +72,8 @@ class FileGenerator {
const Options options_;
void PrintFileRuntimePreamble(
io::Printer* printer, const std::vector<string>& headers_to_import) const;
io::Printer* printer,
const std::vector<std::string>& headers_to_import) const;
};
} // namespace objectivec

@ -50,17 +50,17 @@ bool ObjectiveCGenerator::HasGenerateAll() const {
}
bool ObjectiveCGenerator::Generate(const FileDescriptor* file,
const string& parameter,
const std::string& parameter,
GeneratorContext* context,
string* error) const {
std::string* error) const {
*error = "Unimplemented Generate() method. Call GenerateAll() instead.";
return false;
}
bool ObjectiveCGenerator::GenerateAll(const std::vector<const FileDescriptor*>& files,
const string& parameter,
GeneratorContext* context,
string* error) const {
bool ObjectiveCGenerator::GenerateAll(
const std::vector<const FileDescriptor*>& files,
const std::string& parameter, GeneratorContext* context,
std::string* error) const {
// -----------------------------------------------------------------
// Parse generator options. These options are passed to the compiler using the
// --objc_opt flag. The options are passed as a comma separated list of
@ -71,7 +71,7 @@ bool ObjectiveCGenerator::GenerateAll(const std::vector<const FileDescriptor*>&
Options generation_options;
std::vector<std::pair<string, string> > options;
std::vector<std::pair<std::string, std::string> > options;
ParseGeneratorParameter(parameter, &options);
for (int i = 0; i < options.size(); i++) {
if (options[i].first == "expected_prefixes_path") {
@ -154,7 +154,7 @@ bool ObjectiveCGenerator::GenerateAll(const std::vector<const FileDescriptor*>&
for (int i = 0; i < files.size(); i++) {
const FileDescriptor* file = files[i];
FileGenerator file_generator(file, generation_options);
string filepath = FilePath(file);
std::string filepath = FilePath(file);
// Generate header.
{

@ -58,14 +58,11 @@ class PROTOC_EXPORT ObjectiveCGenerator : public CodeGenerator {
// implements CodeGenerator ----------------------------------------
bool HasGenerateAll() const override;
bool Generate(const FileDescriptor* file,
const string& parameter,
GeneratorContext* context,
string* error) const override;
bool Generate(const FileDescriptor* file, const std::string& parameter,
GeneratorContext* context, std::string* error) const override;
bool GenerateAll(const std::vector<const FileDescriptor*>& files,
const string& parameter,
GeneratorContext* context,
string* error) const override;
const std::string& parameter, GeneratorContext* context,
std::string* error) const override;
uint64_t GetSupportedFeatures() const override {
return FEATURE_PROTO3_OPTIONAL;

@ -85,8 +85,9 @@ Options::Options() {
namespace {
std::unordered_set<string> MakeWordsMap(const char* const words[], size_t num_words) {
std::unordered_set<string> result;
std::unordered_set<std::string> MakeWordsMap(const char* const words[],
size_t num_words) {
std::unordered_set<std::string> result;
for (int i = 0; i < num_words; i++) {
result.insert(words[i]);
}
@ -95,7 +96,7 @@ std::unordered_set<string> MakeWordsMap(const char* const words[], size_t num_wo
const char* const kUpperSegmentsList[] = {"url", "http", "https"};
std::unordered_set<string> kUpperSegments =
std::unordered_set<std::string> kUpperSegments =
MakeWordsMap(kUpperSegmentsList, GOOGLE_ARRAYSIZE(kUpperSegmentsList));
bool ascii_isnewline(char c) {
@ -105,9 +106,10 @@ bool ascii_isnewline(char c) {
// Internal helper for name handing.
// Do not expose this outside of helpers, stick to having functions for specific
// cases (ClassName(), FieldName()), so there is always consistent suffix rules.
string UnderscoresToCamelCase(const string& input, bool first_capitalized) {
std::vector<string> values;
string current;
std::string UnderscoresToCamelCase(const std::string& input,
bool first_capitalized) {
std::vector<std::string> values;
std::string current;
bool last_char_was_number = false;
bool last_char_was_lower = false;
@ -145,10 +147,11 @@ string UnderscoresToCamelCase(const string& input, bool first_capitalized) {
}
values.push_back(current);
string result;
std::string result;
bool first_segment_forces_upper = false;
for (std::vector<string>::iterator i = values.begin(); i != values.end(); ++i) {
string value = *i;
for (std::vector<std::string>::iterator i = values.begin(); i != values.end();
++i) {
std::string value = *i;
bool all_upper = (kUpperSegments.count(value) > 0);
if (all_upper && (result.length() == 0)) {
first_segment_forces_upper = true;
@ -234,7 +237,7 @@ const char* const kReservedWordList[] = {
// but this verifies and allows for future expansion if we decide to redefine what a
// reserved C identifier is (for example the GNU list
// https://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html )
bool IsReservedCIdentifier(const string& input) {
bool IsReservedCIdentifier(const std::string& input) {
if (input.length() > 2) {
if (input.at(0) == '_') {
if (isupper(input.at(1)) || input.at(1) == '_') {
@ -245,15 +248,15 @@ bool IsReservedCIdentifier(const string& input) {
return false;
}
string SanitizeNameForObjC(const string& prefix,
const string& input,
const string& extension,
string* out_suffix_added) {
static const std::unordered_set<string> kReservedWords =
std::string SanitizeNameForObjC(const std::string& prefix,
const std::string& input,
const std::string& extension,
std::string* out_suffix_added) {
static const std::unordered_set<std::string> kReservedWords =
MakeWordsMap(kReservedWordList, GOOGLE_ARRAYSIZE(kReservedWordList));
static const std::unordered_set<string> kNSObjectMethods =
static const std::unordered_set<std::string> kNSObjectMethods =
MakeWordsMap(kNSObjectMethodsList, GOOGLE_ARRAYSIZE(kNSObjectMethodsList));
string sanitized;
std::string sanitized;
// We add the prefix in the cases where the string is missing a prefix.
// We define "missing a prefix" as where 'input':
// a) Doesn't start with the prefix or
@ -278,7 +281,7 @@ string SanitizeNameForObjC(const string& prefix,
return sanitized;
}
string NameFromFieldDescriptor(const FieldDescriptor* field) {
std::string NameFromFieldDescriptor(const FieldDescriptor* field) {
if (field->type() == FieldDescriptor::TYPE_GROUP) {
return field->message_type()->name();
} else {
@ -286,9 +289,10 @@ string NameFromFieldDescriptor(const FieldDescriptor* field) {
}
}
void PathSplit(const string& path, string* directory, string* basename) {
string::size_type last_slash = path.rfind('/');
if (last_slash == string::npos) {
void PathSplit(const std::string& path, std::string* directory,
std::string* basename) {
std::string::size_type last_slash = path.rfind('/');
if (last_slash == std::string::npos) {
if (directory) {
*directory = "";
}
@ -305,7 +309,7 @@ void PathSplit(const string& path, string* directory, string* basename) {
}
}
bool IsSpecialName(const string& name, const string* special_names,
bool IsSpecialName(const std::string& name, const std::string* special_names,
size_t count) {
for (size_t i = 0; i < count; ++i) {
size_t length = special_names[i].length();
@ -323,7 +327,7 @@ bool IsSpecialName(const string& name, const string* special_names,
return false;
}
string GetZeroEnumNameForFlagType(const FlagType flag_type) {
std::string GetZeroEnumNameForFlagType(const FlagType flag_type) {
switch(flag_type) {
case FLAGTYPE_DESCRIPTOR_INITIALIZATION:
return "GPBDescriptorInitializationFlag_None";
@ -337,7 +341,7 @@ string GetZeroEnumNameForFlagType(const FlagType flag_type) {
}
}
string GetEnumNameForFlagType(const FlagType flag_type) {
std::string GetEnumNameForFlagType(const FlagType flag_type) {
switch(flag_type) {
case FLAGTYPE_DESCRIPTOR_INITIALIZATION:
return "GPBDescriptorInitializationFlags";
@ -347,18 +351,18 @@ string GetEnumNameForFlagType(const FlagType flag_type) {
return "GPBFieldFlags";
default:
GOOGLE_LOG(FATAL) << "Can't get here.";
return string();
return std::string();
}
}
} // namespace
// Escape C++ trigraphs by escaping question marks to \?
string EscapeTrigraphs(const string& to_escape) {
std::string EscapeTrigraphs(const std::string& to_escape) {
return StringReplace(to_escape, "?", "\\?", true);
}
string StripProto(const string& filename) {
std::string StripProto(const std::string& filename) {
if (HasSuffixString(filename, ".protodevel")) {
return StripSuffixString(filename, ".protodevel");
} else {
@ -375,38 +379,37 @@ void TrimWhitespace(StringPiece* input) {
}
}
bool IsRetainedName(const string& name) {
bool IsRetainedName(const std::string& name) {
// List of prefixes from
// http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html
static const string retained_names[] = {"new", "alloc", "copy",
"mutableCopy"};
static const std::string retained_names[] = {"new", "alloc", "copy",
"mutableCopy"};
return IsSpecialName(name, retained_names,
sizeof(retained_names) / sizeof(retained_names[0]));
}
bool IsInitName(const string& name) {
static const string init_names[] = {"init"};
bool IsInitName(const std::string& name) {
static const std::string init_names[] = {"init"};
return IsSpecialName(name, init_names,
sizeof(init_names) / sizeof(init_names[0]));
}
string BaseFileName(const FileDescriptor* file) {
string basename;
std::string BaseFileName(const FileDescriptor* file) {
std::string basename;
PathSplit(file->name(), NULL, &basename);
return basename;
}
string FileClassPrefix(const FileDescriptor* file) {
std::string FileClassPrefix(const FileDescriptor* file) {
// Default is empty string, no need to check has_objc_class_prefix.
string result = file->options().objc_class_prefix();
std::string result = file->options().objc_class_prefix();
return result;
}
string FilePath(const FileDescriptor* file) {
string output;
string basename;
string directory;
std::string FilePath(const FileDescriptor* file) {
std::string output;
std::string basename;
std::string directory;
PathSplit(file->name(), &directory, &basename);
if (directory.length() > 0) {
output = directory + "/";
@ -420,10 +423,10 @@ string FilePath(const FileDescriptor* file) {
return output;
}
string FilePathBasename(const FileDescriptor* file) {
string output;
string basename;
string directory;
std::string FilePathBasename(const FileDescriptor* file) {
std::string output;
std::string basename;
std::string directory;
PathSplit(file->name(), &directory, &basename);
basename = StripProto(basename);
@ -433,16 +436,17 @@ string FilePathBasename(const FileDescriptor* file) {
return output;
}
string FileClassName(const FileDescriptor* file) {
const string prefix = FileClassPrefix(file);
const string name = UnderscoresToCamelCase(StripProto(BaseFileName(file)), true) + "Root";
std::string FileClassName(const FileDescriptor* file) {
const std::string prefix = FileClassPrefix(file);
const std::string name =
UnderscoresToCamelCase(StripProto(BaseFileName(file)), true) + "Root";
// There aren't really any reserved words that end in "Root", but playing
// it safe and checking.
return SanitizeNameForObjC(prefix, name, "_RootClass", NULL);
}
string ClassNameWorker(const Descriptor* descriptor) {
string name;
std::string ClassNameWorker(const Descriptor* descriptor) {
std::string name;
if (descriptor->containing_type() != NULL) {
name = ClassNameWorker(descriptor->containing_type());
name += "_";
@ -450,8 +454,8 @@ string ClassNameWorker(const Descriptor* descriptor) {
return name + descriptor->name();
}
string ClassNameWorker(const EnumDescriptor* descriptor) {
string name;
std::string ClassNameWorker(const EnumDescriptor* descriptor) {
std::string name;
if (descriptor->containing_type() != NULL) {
name = ClassNameWorker(descriptor->containing_type());
name += "_";
@ -459,19 +463,20 @@ string ClassNameWorker(const EnumDescriptor* descriptor) {
return name + descriptor->name();
}
string ClassName(const Descriptor* descriptor) {
std::string ClassName(const Descriptor* descriptor) {
return ClassName(descriptor, NULL);
}
string ClassName(const Descriptor* descriptor, string* out_suffix_added) {
std::string ClassName(const Descriptor* descriptor,
std::string* out_suffix_added) {
// 1. Message names are used as is (style calls for CamelCase, trust it).
// 2. Check for reserved word at the very end and then suffix things.
const string prefix = FileClassPrefix(descriptor->file());
const string name = ClassNameWorker(descriptor);
const std::string prefix = FileClassPrefix(descriptor->file());
const std::string name = ClassNameWorker(descriptor);
return SanitizeNameForObjC(prefix, name, "_Class", out_suffix_added);
}
string EnumName(const EnumDescriptor* descriptor) {
std::string EnumName(const EnumDescriptor* descriptor) {
// 1. Enum names are used as is (style calls for CamelCase, trust it).
// 2. Check for reserved word at the every end and then suffix things.
// message Fixed {
@ -480,27 +485,28 @@ string EnumName(const EnumDescriptor* descriptor) {
// ...
// }
// yields Fixed_Class, Fixed_Size.
const string prefix = FileClassPrefix(descriptor->file());
const string name = ClassNameWorker(descriptor);
const std::string prefix = FileClassPrefix(descriptor->file());
const std::string name = ClassNameWorker(descriptor);
return SanitizeNameForObjC(prefix, name, "_Enum", NULL);
}
string EnumValueName(const EnumValueDescriptor* descriptor) {
std::string EnumValueName(const EnumValueDescriptor* descriptor) {
// Because of the Switch enum compatibility, the name on the enum has to have
// the suffix handing, so it slightly diverges from how nested classes work.
// enum Fixed {
// FOO = 1
// }
// yields Fixed_Enum and Fixed_Enum_Foo (not Fixed_Foo).
const string class_name = EnumName(descriptor->type());
const string value_str = UnderscoresToCamelCase(descriptor->name(), true);
const string name = class_name + "_" + value_str;
const std::string class_name = EnumName(descriptor->type());
const std::string value_str =
UnderscoresToCamelCase(descriptor->name(), true);
const std::string name = class_name + "_" + value_str;
// There aren't really any reserved words with an underscore and a leading
// capital letter, but playing it safe and checking.
return SanitizeNameForObjC("", name, "_Value", NULL);
}
string EnumValueShortName(const EnumValueDescriptor* descriptor) {
std::string EnumValueShortName(const EnumValueDescriptor* descriptor) {
// Enum value names (EnumValueName above) are the enum name turned into
// a class name and then the value name is CamelCased and concatenated; the
// whole thing then gets sanitized for reserved words.
@ -513,14 +519,14 @@ string EnumValueShortName(const EnumValueDescriptor* descriptor) {
// So the right way to get the short name is to take the full enum name
// and then strip off the enum name (leaving the value name and anything
// done by sanitize).
const string class_name = EnumName(descriptor->type());
const string long_name_prefix = class_name + "_";
const string long_name = EnumValueName(descriptor);
const std::string class_name = EnumName(descriptor->type());
const std::string long_name_prefix = class_name + "_";
const std::string long_name = EnumValueName(descriptor);
return StripPrefixString(long_name, long_name_prefix);
}
string UnCamelCaseEnumShortName(const string& name) {
string result;
std::string UnCamelCaseEnumShortName(const std::string& name) {
std::string result;
for (int i = 0; i < name.size(); i++) {
char c = name[i];
if (i > 0 && ascii_isupper(c)) {
@ -531,15 +537,15 @@ string UnCamelCaseEnumShortName(const string& name) {
return result;
}
string ExtensionMethodName(const FieldDescriptor* descriptor) {
const string name = NameFromFieldDescriptor(descriptor);
const string result = UnderscoresToCamelCase(name, false);
std::string ExtensionMethodName(const FieldDescriptor* descriptor) {
const std::string name = NameFromFieldDescriptor(descriptor);
const std::string result = UnderscoresToCamelCase(name, false);
return SanitizeNameForObjC("", result, "_Extension", NULL);
}
string FieldName(const FieldDescriptor* field) {
const string name = NameFromFieldDescriptor(field);
string result = UnderscoresToCamelCase(name, false);
std::string FieldName(const FieldDescriptor* field) {
const std::string name = NameFromFieldDescriptor(field);
std::string result = UnderscoresToCamelCase(name, false);
if (field->is_repeated() && !field->is_map()) {
// Add "Array" before do check for reserved worlds.
result += "Array";
@ -552,50 +558,50 @@ string FieldName(const FieldDescriptor* field) {
return SanitizeNameForObjC("", result, "_p", NULL);
}
string FieldNameCapitalized(const FieldDescriptor* field) {
std::string FieldNameCapitalized(const FieldDescriptor* field) {
// Want the same suffix handling, so upcase the first letter of the other
// name.
string result = FieldName(field);
std::string result = FieldName(field);
if (result.length() > 0) {
result[0] = ascii_toupper(result[0]);
}
return result;
}
string OneofEnumName(const OneofDescriptor* descriptor) {
std::string OneofEnumName(const OneofDescriptor* descriptor) {
const Descriptor* fieldDescriptor = descriptor->containing_type();
string name = ClassName(fieldDescriptor);
std::string name = ClassName(fieldDescriptor);
name += "_" + UnderscoresToCamelCase(descriptor->name(), true) + "_OneOfCase";
// No sanitize needed because the OS never has names that end in _OneOfCase.
return name;
}
string OneofName(const OneofDescriptor* descriptor) {
string name = UnderscoresToCamelCase(descriptor->name(), false);
std::string OneofName(const OneofDescriptor* descriptor) {
std::string name = UnderscoresToCamelCase(descriptor->name(), false);
// No sanitize needed because it gets OneOfCase added and that shouldn't
// ever conflict.
return name;
}
string OneofNameCapitalized(const OneofDescriptor* descriptor) {
std::string OneofNameCapitalized(const OneofDescriptor* descriptor) {
// Use the common handling and then up-case the first letter.
string result = OneofName(descriptor);
std::string result = OneofName(descriptor);
if (result.length() > 0) {
result[0] = ascii_toupper(result[0]);
}
return result;
}
string ObjCClass(const string& class_name) {
return string("GPBObjCClass(") + class_name + ")";
std::string ObjCClass(const std::string& class_name) {
return std::string("GPBObjCClass(") + class_name + ")";
}
string ObjCClassDeclaration(const string& class_name) {
return string("GPBObjCClassDeclaration(") + class_name + ");";
std::string ObjCClassDeclaration(const std::string& class_name) {
return std::string("GPBObjCClassDeclaration(") + class_name + ");";
}
string UnCamelCaseFieldName(const string& name, const FieldDescriptor* field) {
string worker(name);
std::string UnCamelCaseFieldName(const std::string& name, const FieldDescriptor* field) {
std::string worker(name);
if (HasSuffixString(worker, "_p")) {
worker = StripSuffixString(worker, "_p");
}
@ -610,7 +616,7 @@ string UnCamelCaseFieldName(const string& name, const FieldDescriptor* field) {
}
return worker;
} else {
string result;
std::string result;
for (int i = 0; i < worker.size(); i++) {
char c = worker[i];
if (ascii_isupper(c)) {
@ -626,7 +632,7 @@ string UnCamelCaseFieldName(const string& name, const FieldDescriptor* field) {
}
}
string GetCapitalizedType(const FieldDescriptor* field) {
std::string GetCapitalizedType(const FieldDescriptor* field) {
switch (field->type()) {
case FieldDescriptor::TYPE_INT32:
return "Int32";
@ -669,7 +675,7 @@ string GetCapitalizedType(const FieldDescriptor* field) {
// Some compilers report reaching end of function even though all cases of
// the enum are handed in the switch.
GOOGLE_LOG(FATAL) << "Can't get here.";
return string();
return std::string();
}
ObjectiveCType GetObjectiveCType(FieldDescriptor::Type field_type) {
@ -743,7 +749,8 @@ bool IsReferenceType(const FieldDescriptor* field) {
return !IsPrimitiveType(field);
}
static string HandleExtremeFloatingPoint(string val, bool add_float_suffix) {
static std::string HandleExtremeFloatingPoint(std::string val,
bool add_float_suffix) {
if (val == "nan") {
return "NAN";
} else if (val == "inf") {
@ -752,16 +759,16 @@ static string HandleExtremeFloatingPoint(string val, bool add_float_suffix) {
return "-INFINITY";
} else {
// float strings with ., e or E need to have f appended
if (add_float_suffix &&
(val.find(".") != string::npos || val.find("e") != string::npos ||
val.find("E") != string::npos)) {
if (add_float_suffix && (val.find(".") != std::string::npos ||
val.find("e") != std::string::npos ||
val.find("E") != std::string::npos)) {
val += "f";
}
return val;
}
}
string GPBGenericValueFieldName(const FieldDescriptor* field) {
std::string GPBGenericValueFieldName(const FieldDescriptor* field) {
// Returns the field within the GPBGenericValue union to use for the given
// field.
if (field->is_repeated()) {
@ -797,11 +804,11 @@ string GPBGenericValueFieldName(const FieldDescriptor* field) {
// Some compilers report reaching end of function even though all cases of
// the enum are handed in the switch.
GOOGLE_LOG(FATAL) << "Can't get here.";
return string();
return std::string();
}
string DefaultValue(const FieldDescriptor* field) {
std::string DefaultValue(const FieldDescriptor* field) {
// Repeated fields don't have defaults.
if (field->is_repeated()) {
return "nil";
@ -836,7 +843,7 @@ string DefaultValue(const FieldDescriptor* field) {
return field->default_value_bool() ? "YES" : "NO";
case FieldDescriptor::CPPTYPE_STRING: {
const bool has_default_value = field->has_default_value();
const string& default_string = field->default_value_string();
const std::string& default_string = field->default_value_string();
if (!has_default_value || default_string.length() == 0) {
// If the field is defined as being the empty string,
// then we will just assign to nil, as the empty string is the
@ -853,7 +860,7 @@ string DefaultValue(const FieldDescriptor* field) {
// Must convert to a standard byte order for packing length into
// a cstring.
uint32 length = ghtonl(default_string.length());
string bytes((const char*)&length, sizeof(length));
std::string bytes((const char*)&length, sizeof(length));
bytes.append(default_string);
return "(NSData*)\"" + EscapeTrigraphs(CEscape(bytes)) + "\"";
} else {
@ -869,7 +876,7 @@ string DefaultValue(const FieldDescriptor* field) {
// Some compilers report reaching end of function even though all cases of
// the enum are handed in the switch.
GOOGLE_LOG(FATAL) << "Can't get here.";
return string();
return std::string();
}
bool HasNonZeroDefaultValue(const FieldDescriptor* field) {
@ -902,7 +909,7 @@ bool HasNonZeroDefaultValue(const FieldDescriptor* field) {
case FieldDescriptor::CPPTYPE_BOOL:
return field->default_value_bool();
case FieldDescriptor::CPPTYPE_STRING: {
const string& default_string = field->default_value_string();
const std::string& default_string = field->default_value_string();
return default_string.length() != 0;
}
case FieldDescriptor::CPPTYPE_ENUM:
@ -917,14 +924,14 @@ bool HasNonZeroDefaultValue(const FieldDescriptor* field) {
return false;
}
string BuildFlagsString(const FlagType flag_type,
const std::vector<string>& strings) {
std::string BuildFlagsString(const FlagType flag_type,
const std::vector<std::string>& strings) {
if (strings.empty()) {
return GetZeroEnumNameForFlagType(flag_type);
} else if (strings.size() == 1) {
return strings[0];
}
string string("(" + GetEnumNameForFlagType(flag_type) + ")(");
std::string string("(" + GetEnumNameForFlagType(flag_type) + ")(");
for (size_t i = 0; i != strings.size(); ++i) {
if (i > 0) {
string.append(" | ");
@ -935,12 +942,12 @@ string BuildFlagsString(const FlagType flag_type,
return string;
}
string BuildCommentsString(const SourceLocation& location,
std::string BuildCommentsString(const SourceLocation& location,
bool prefer_single_line) {
const string& comments = location.leading_comments.empty()
const std::string& comments = location.leading_comments.empty()
? location.trailing_comments
: location.leading_comments;
std::vector<string> lines;
std::vector<std::string> lines;
lines = Split(comments, "\n", false);
while (!lines.empty() && lines.back().empty()) {
lines.pop_back();
@ -950,10 +957,10 @@ string BuildCommentsString(const SourceLocation& location,
return "";
}
string prefix;
string suffix;
string final_comments;
string epilogue;
std::string prefix;
std::string suffix;
std::string final_comments;
std::string epilogue;
bool add_leading_space = false;
@ -969,7 +976,7 @@ string BuildCommentsString(const SourceLocation& location,
}
for (int i = 0; i < lines.size(); i++) {
string line = StripPrefixString(lines[i], " ");
std::string line = StripPrefixString(lines[i], " ");
// HeaderDoc and appledoc use '\' and '@' for markers; escape them.
line = StringReplace(line, "\\", "\\\\", true);
line = StringReplace(line, "@", "\\@", true);
@ -993,9 +1000,9 @@ string BuildCommentsString(const SourceLocation& location,
// use a different value; so it isn't as simple as a option.
const char* const ProtobufLibraryFrameworkName = "Protobuf";
string ProtobufFrameworkImportSymbol(const string& framework_name) {
std::string ProtobufFrameworkImportSymbol(const std::string& framework_name) {
// GPB_USE_[framework_name]_FRAMEWORK_IMPORTS
string result = string("GPB_USE_");
std::string result = std::string("GPB_USE_");
result += ToUpper(framework_name);
result += "_FRAMEWORK_IMPORTS";
return result;
@ -1005,7 +1012,7 @@ bool IsProtobufLibraryBundledProtoFile(const FileDescriptor* file) {
// We don't check the name prefix or proto package because some files
// (descriptor.proto), aren't shipped generated by the library, so this
// seems to be the safest way to only catch the ones shipped.
const string name = file->name();
const std::string name = file->name();
if (name == "google/protobuf/any.proto" ||
name == "google/protobuf/api.proto" ||
name == "google/protobuf/duration.proto" ||
@ -1044,21 +1051,21 @@ namespace {
class ExpectedPrefixesCollector : public LineConsumer {
public:
ExpectedPrefixesCollector(std::map<string, string>* inout_package_to_prefix_map)
ExpectedPrefixesCollector(std::map<std::string, std::string>* inout_package_to_prefix_map)
: prefix_map_(inout_package_to_prefix_map) {}
virtual bool ConsumeLine(const StringPiece& line, string* out_error);
virtual bool ConsumeLine(const StringPiece& line, std::string* out_error);
private:
std::map<string, string>* prefix_map_;
std::map<std::string, std::string>* prefix_map_;
};
bool ExpectedPrefixesCollector::ConsumeLine(
const StringPiece& line, string* out_error) {
const StringPiece& line, std::string* out_error) {
int offset = line.find('=');
if (offset == StringPiece::npos) {
*out_error = string("Expected prefixes file line without equal sign: '") +
string(line) + "'.";
*out_error = std::string("Expected prefixes file line without equal sign: '") +
std::string(line) + "'.";
return false;
}
StringPiece package = line.substr(0, offset);
@ -1067,13 +1074,13 @@ bool ExpectedPrefixesCollector::ConsumeLine(
TrimWhitespace(&prefix);
// Don't really worry about error checking the package/prefix for
// being valid. Assume the file is validated when it is created/edited.
(*prefix_map_)[string(package)] = string(prefix);
(*prefix_map_)[std::string(package)] = std::string(prefix);
return true;
}
bool LoadExpectedPackagePrefixes(const Options &generation_options,
std::map<string, string>* prefix_map,
string* out_error) {
bool LoadExpectedPackagePrefixes(const Options& generation_options,
std::map<std::string, std::string>* prefix_map,
std::string* out_error) {
if (generation_options.expected_prefixes_path.empty()) {
return true;
}
@ -1084,19 +1091,18 @@ bool LoadExpectedPackagePrefixes(const Options &generation_options,
}
bool ValidateObjCClassPrefix(
const FileDescriptor* file,
const string& expected_prefixes_path,
const std::map<string, string>& expected_package_prefixes,
string* out_error) {
const string prefix = file->options().objc_class_prefix();
const string package = file->package();
const FileDescriptor* file, const std::string& expected_prefixes_path,
const std::map<std::string, std::string>& expected_package_prefixes,
std::string* out_error) {
const std::string prefix = file->options().objc_class_prefix();
const std::string package = file->package();
// NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
// error cases, so it seems to be ok to use as a back door for warnings.
// Check: Error - See if there was an expected prefix for the package and
// report if it doesn't match (wrong or missing).
std::map<string, string>::const_iterator package_match =
std::map<std::string, std::string>::const_iterator package_match =
expected_package_prefixes.find(package);
if (package_match != expected_package_prefixes.end()) {
// There was an entry, and...
@ -1126,7 +1132,7 @@ bool ValidateObjCClassPrefix(
// to Apple's rules (the checks above implicitly whitelist anything that
// doesn't meet these rules).
if (!ascii_isupper(prefix[0])) {
std::cerr << std::endl
std::cerr
<< "protoc:0: warning: Invalid 'option objc_class_prefix = \""
<< prefix << "\";' in '" << file->name() << "';"
<< " it should start with a capital letter." << std::endl;
@ -1135,7 +1141,7 @@ bool ValidateObjCClassPrefix(
if (prefix.length() < 3) {
// Apple reserves 2 character prefixes for themselves. They do use some
// 3 character prefixes, but they haven't updated the rules/docs.
std::cerr << std::endl
std::cerr
<< "protoc:0: warning: Invalid 'option objc_class_prefix = \""
<< prefix << "\";' in '" << file->name() << "';"
<< " Apple recommends they should be at least 3 characters long."
@ -1144,8 +1150,9 @@ bool ValidateObjCClassPrefix(
}
// Look for any other package that uses the same prefix.
string other_package_for_prefix;
for (std::map<string, string>::const_iterator i = expected_package_prefixes.begin();
std::string other_package_for_prefix;
for (std::map<std::string, std::string>::const_iterator i =
expected_package_prefixes.begin();
i != expected_package_prefixes.end(); ++i) {
if (i->second == prefix) {
other_package_for_prefix = i->first;
@ -1159,7 +1166,7 @@ bool ValidateObjCClassPrefix(
// The file does not have a package and ...
if (other_package_for_prefix.empty()) {
// ... no other package has declared that prefix.
std::cerr << std::endl
std::cerr
<< "protoc:0: warning: File '" << file->name() << "' has no "
<< "package. Consider adding a new package to the proto and adding '"
<< "new.package = " << prefix << "' to the expected prefixes file ("
@ -1167,7 +1174,7 @@ bool ValidateObjCClassPrefix(
std::cerr.flush();
} else {
// ... another package has declared the same prefix.
std::cerr << std::endl
std::cerr
<< "protoc:0: warning: File '" << file->name() << "' has no package "
<< "and package '" << other_package_for_prefix << "' already uses '"
<< prefix << "' as its prefix. Consider either adding a new package "
@ -1196,7 +1203,7 @@ bool ValidateObjCClassPrefix(
// Check: Warning - If the given package/prefix pair wasn't expected, issue a
// warning issue a warning suggesting it gets added to the file.
if (!expected_package_prefixes.empty()) {
std::cerr << std::endl
std::cerr
<< "protoc:0: warning: Found unexpected 'option objc_class_prefix = \""
<< prefix << "\";' in '" << file->name() << "';"
<< " consider adding it to the expected prefixes file ("
@ -1211,9 +1218,9 @@ bool ValidateObjCClassPrefix(
bool ValidateObjCClassPrefixes(const std::vector<const FileDescriptor*>& files,
const Options& generation_options,
string* out_error) {
std::string* out_error) {
// Load the expected package prefixes, if available, to validate against.
std::map<string, string> expected_package_prefixes;
std::map<std::string, std::string> expected_package_prefixes;
if (!LoadExpectedPackagePrefixes(generation_options,
&expected_package_prefixes,
out_error)) {
@ -1247,8 +1254,8 @@ TextFormatDecodeData::TextFormatDecodeData() { }
TextFormatDecodeData::~TextFormatDecodeData() { }
void TextFormatDecodeData::AddString(int32 key,
const string& input_for_decode,
const string& desired_output) {
const std::string& input_for_decode,
const std::string& desired_output) {
for (std::vector<DataEntry>::const_iterator i = entries_.begin();
i != entries_.end(); ++i) {
if (i->first == key) {
@ -1260,12 +1267,12 @@ void TextFormatDecodeData::AddString(int32 key,
}
}
const string& data = TextFormatDecodeData::DecodeDataForString(
const std::string& data = TextFormatDecodeData::DecodeDataForString(
input_for_decode, desired_output);
entries_.push_back(DataEntry(key, data));
}
string TextFormatDecodeData::Data() const {
std::string TextFormatDecodeData::Data() const {
std::ostringstream data_stringstream;
if (num_entries() > 0) {
@ -1296,7 +1303,7 @@ class DecodeDataBuilder {
Push();
need_underscore_ = true;
}
string Finish() {
std::string Finish() {
Push();
return decode_data_;
}
@ -1352,7 +1359,7 @@ class DecodeDataBuilder {
uint8 op_;
int segment_len_;
string decode_data_;
std::string decode_data_;
};
bool DecodeDataBuilder::AddCharacter(const char desired, const char input) {
@ -1393,8 +1400,8 @@ bool DecodeDataBuilder::AddCharacter(const char desired, const char input) {
// If decode data can't be generated, a directive for the raw string
// is used instead.
string DirectDecodeString(const string& str) {
string result;
std::string DirectDecodeString(const std::string& str) {
std::string result;
result += (char)'\0'; // Marker for full string.
result += str;
result += (char)'\0'; // End of string.
@ -1404,8 +1411,8 @@ string DirectDecodeString(const string& str) {
} // namespace
// static
string TextFormatDecodeData::DecodeDataForString(const string& input_for_decode,
const string& desired_output) {
std::string TextFormatDecodeData::DecodeDataForString(
const std::string& input_for_decode, const std::string& desired_output) {
if (input_for_decode.empty() || desired_output.empty()) {
std::cerr << "error: got empty string for making TextFormat data, input: \""
<< input_for_decode << "\", desired: \"" << desired_output << "\"."
@ -1413,8 +1420,8 @@ string TextFormatDecodeData::DecodeDataForString(const string& input_for_decode,
std::cerr.flush();
abort();
}
if ((input_for_decode.find('\0') != string::npos) ||
(desired_output.find('\0') != string::npos)) {
if ((input_for_decode.find('\0') != std::string::npos) ||
(desired_output.find('\0') != std::string::npos)) {
std::cerr << "error: got a null char in a string for making TextFormat data,"
<< " input: \"" << CEscape(input_for_decode) << "\", desired: \""
<< CEscape(desired_output) << "\"." << std::endl;
@ -1469,21 +1476,21 @@ class Parser {
bool Finish();
int last_line() const { return line_; }
string error_str() const { return error_str_; }
std::string error_str() const { return error_str_; }
private:
bool ParseLoop();
LineConsumer* line_consumer_;
int line_;
string error_str_;
std::string error_str_;
StringPiece p_;
string leftover_;
std::string leftover_;
};
bool Parser::ParseChunk(StringPiece chunk) {
if (!leftover_.empty()) {
leftover_ += string(chunk);
leftover_ += std::string(chunk);
p_ = StringPiece(leftover_);
} else {
p_ = chunk;
@ -1492,7 +1499,7 @@ bool Parser::ParseChunk(StringPiece chunk) {
if (p_.empty()) {
leftover_.clear();
} else {
leftover_ = string(p_);
leftover_ = std::string(p_);
}
return result;
}
@ -1532,15 +1539,15 @@ LineConsumer::LineConsumer() {}
LineConsumer::~LineConsumer() {}
bool ParseSimpleFile(
const string& path, LineConsumer* line_consumer, string* out_error) {
bool ParseSimpleFile(const std::string& path, LineConsumer* line_consumer,
std::string* out_error) {
int fd;
do {
fd = posix::open(path.c_str(), O_RDONLY);
} while (fd < 0 && errno == EINTR);
if (fd < 0) {
*out_error =
string("error: Unable to open \"") + path + "\", " + strerror(errno);
*out_error = std::string("error: Unable to open \"") + path + "\", " +
strerror(errno);
return false;
}
io::FileInputStream file_stream(fd);
@ -1556,7 +1563,7 @@ bool ParseSimpleFile(
if (!parser.ParseChunk(StringPiece(static_cast<const char*>(buf), buf_len))) {
*out_error =
string("error: ") + path +
std::string("error: ") + path +
" Line " + StrCat(parser.last_line()) + ", " + parser.error_str();
return false;
}
@ -1565,29 +1572,27 @@ bool ParseSimpleFile(
}
ImportWriter::ImportWriter(
const string& generate_for_named_framework,
const string& named_framework_to_proto_path_mappings_path,
const string& runtime_import_prefix,
bool include_wkt_imports)
const std::string& generate_for_named_framework,
const std::string& named_framework_to_proto_path_mappings_path,
const std::string& runtime_import_prefix, bool include_wkt_imports)
: generate_for_named_framework_(generate_for_named_framework),
named_framework_to_proto_path_mappings_path_(
named_framework_to_proto_path_mappings_path),
runtime_import_prefix_(runtime_import_prefix),
include_wkt_imports_(include_wkt_imports),
need_to_parse_mapping_file_(true) {
}
need_to_parse_mapping_file_(true) {}
ImportWriter::~ImportWriter() {}
void ImportWriter::AddFile(const FileDescriptor* file,
const string& header_extension) {
const std::string& header_extension) {
if (IsProtobufLibraryBundledProtoFile(file)) {
// The imports of the WKTs are only needed within the library itself,
// in other cases, they get skipped because the generated code already
// import GPBProtocolBuffers.h and hence proves them.
if (include_wkt_imports_) {
const string header_name =
"GPB" + FilePathBasename(file) + header_extension;
const std::string header_name =
"GPB" + FilePathBasename(file) + header_extension;
protobuf_imports_.push_back(header_name);
}
return;
@ -1598,7 +1603,7 @@ void ImportWriter::AddFile(const FileDescriptor* file,
ParseFrameworkMappings();
}
std::map<string, string>::iterator proto_lookup =
std::map<std::string, std::string>::iterator proto_lookup =
proto_file_to_framework_name_.find(file->name());
if (proto_lookup != proto_file_to_framework_name_.end()) {
other_framework_imports_.push_back(
@ -1630,7 +1635,8 @@ void ImportWriter::Print(io::Printer* printer) const {
printer->Print("\n");
}
for (std::vector<string>::const_iterator iter = other_framework_imports_.begin();
for (std::vector<std::string>::const_iterator iter =
other_framework_imports_.begin();
iter != other_framework_imports_.end(); ++iter) {
printer->Print(
"#import <$header$>\n",
@ -1645,7 +1651,7 @@ void ImportWriter::Print(io::Printer* printer) const {
printer->Print("\n");
}
for (std::vector<string>::const_iterator iter = other_imports_.begin();
for (std::vector<std::string>::const_iterator iter = other_imports_.begin();
iter != other_imports_.end(); ++iter) {
printer->Print(
"#import \"$header$\"\n",
@ -1655,11 +1661,8 @@ void ImportWriter::Print(io::Printer* printer) const {
}
void ImportWriter::PrintRuntimeImports(
io::Printer* printer,
const std::vector<string>& header_to_import,
const string& runtime_import_prefix,
bool default_cpp_symbol) {
io::Printer* printer, const std::vector<std::string>& header_to_import,
const std::string& runtime_import_prefix, bool default_cpp_symbol) {
// Given an override, use that.
if (!runtime_import_prefix.empty()) {
for (const auto& header : header_to_import) {
@ -1671,8 +1674,8 @@ void ImportWriter::PrintRuntimeImports(
return;
}
const string framework_name(ProtobufLibraryFrameworkName);
const string cpp_symbol(ProtobufFrameworkImportSymbol(framework_name));
const std::string framework_name(ProtobufLibraryFrameworkName);
const std::string cpp_symbol(ProtobufFrameworkImportSymbol(framework_name));
if (default_cpp_symbol) {
printer->Print(
@ -1712,7 +1715,7 @@ void ImportWriter::ParseFrameworkMappings() {
}
ProtoFrameworkCollector collector(&proto_file_to_framework_name_);
string parse_error;
std::string parse_error;
if (!ParseSimpleFile(named_framework_to_proto_path_mappings_path_,
&collector, &parse_error)) {
std::cerr << "error parsing " << named_framework_to_proto_path_mappings_path_
@ -1722,12 +1725,12 @@ void ImportWriter::ParseFrameworkMappings() {
}
bool ImportWriter::ProtoFrameworkCollector::ConsumeLine(
const StringPiece& line, string* out_error) {
const StringPiece& line, std::string* out_error) {
int offset = line.find(':');
if (offset == StringPiece::npos) {
*out_error =
string("Framework/proto file mapping line without colon sign: '") +
string(line) + "'.";
std::string("Framework/proto file mapping line without colon sign: '") +
std::string(line) + "'.";
return false;
}
StringPiece framework_name = line.substr(0, offset);
@ -1744,12 +1747,12 @@ bool ImportWriter::ProtoFrameworkCollector::ConsumeLine(
StringPiece proto_file = proto_file_list.substr(start, offset - start);
TrimWhitespace(&proto_file);
if (!proto_file.empty()) {
std::map<string, string>::iterator existing_entry =
std::map<std::string, std::string>::iterator existing_entry =
map_->find(string(proto_file));
if (existing_entry != map_->end()) {
std::cerr << "warning: duplicate proto file reference, replacing "
"framework entry for '"
<< string(proto_file) << "' with '" << string(framework_name)
<< std::string(proto_file) << "' with '" << std::string(framework_name)
<< "' (was '" << existing_entry->second << "')." << std::endl;
std::cerr.flush();
}
@ -1757,11 +1760,11 @@ bool ImportWriter::ProtoFrameworkCollector::ConsumeLine(
if (proto_file.find(' ') != StringPiece::npos) {
std::cerr << "note: framework mapping file had a proto file with a "
"space in, hopefully that isn't a missing comma: '"
<< string(proto_file) << "'" << std::endl;
<< std::string(proto_file) << "'" << std::endl;
std::cerr.flush();
}
(*map_)[string(proto_file)] = string(framework_name);
(*map_)[std::string(proto_file)] = std::string(framework_name);
}
start = offset + 1;
@ -1770,7 +1773,6 @@ bool ImportWriter::ProtoFrameworkCollector::ConsumeLine(
return true;
}
} // namespace objectivec
} // namespace compiler
} // namespace protobuf

@ -49,83 +49,83 @@ namespace objectivec {
// Generator options (see objectivec_generator.cc for a description of each):
struct Options {
Options();
string expected_prefixes_path;
std::vector<string> expected_prefixes_suppressions;
string generate_for_named_framework;
string named_framework_to_proto_path_mappings_path;
string runtime_import_prefix;
std::string expected_prefixes_path;
std::vector<std::string> expected_prefixes_suppressions;
std::string generate_for_named_framework;
std::string named_framework_to_proto_path_mappings_path;
std::string runtime_import_prefix;
};
// Escape C++ trigraphs by escaping question marks to "\?".
string PROTOC_EXPORT EscapeTrigraphs(const string& to_escape);
std::string PROTOC_EXPORT EscapeTrigraphs(const std::string& to_escape);
// Strips ".proto" or ".protodevel" from the end of a filename.
string PROTOC_EXPORT StripProto(const string& filename);
std::string PROTOC_EXPORT StripProto(const std::string& filename);
// Remove white space from either end of a StringPiece.
void PROTOC_EXPORT TrimWhitespace(StringPiece* input);
// Returns true if the name requires a ns_returns_not_retained attribute applied
// to it.
bool PROTOC_EXPORT IsRetainedName(const string& name);
bool PROTOC_EXPORT IsRetainedName(const std::string& name);
// Returns true if the name starts with "init" and will need to have special
// handling under ARC.
bool PROTOC_EXPORT IsInitName(const string& name);
bool PROTOC_EXPORT IsInitName(const std::string& name);
// Gets the objc_class_prefix.
string PROTOC_EXPORT FileClassPrefix(const FileDescriptor* file);
std::string PROTOC_EXPORT FileClassPrefix(const FileDescriptor* file);
// Gets the path of the file we're going to generate (sans the .pb.h
// extension). The path will be dependent on the objectivec package
// declared in the proto package.
string PROTOC_EXPORT FilePath(const FileDescriptor* file);
std::string PROTOC_EXPORT FilePath(const FileDescriptor* file);
// Just like FilePath(), but without the directory part.
string PROTOC_EXPORT FilePathBasename(const FileDescriptor* file);
std::string PROTOC_EXPORT FilePathBasename(const FileDescriptor* file);
// Gets the name of the root class we'll generate in the file. This class
// is not meant for external consumption, but instead contains helpers that
// the rest of the classes need
string PROTOC_EXPORT FileClassName(const FileDescriptor* file);
std::string PROTOC_EXPORT FileClassName(const FileDescriptor* file);
// These return the fully-qualified class name corresponding to the given
// descriptor.
string PROTOC_EXPORT ClassName(const Descriptor* descriptor);
string PROTOC_EXPORT ClassName(const Descriptor* descriptor,
string* out_suffix_added);
string PROTOC_EXPORT EnumName(const EnumDescriptor* descriptor);
std::string PROTOC_EXPORT ClassName(const Descriptor* descriptor);
std::string PROTOC_EXPORT ClassName(const Descriptor* descriptor,
std::string* out_suffix_added);
std::string PROTOC_EXPORT EnumName(const EnumDescriptor* descriptor);
// Returns the fully-qualified name of the enum value corresponding to the
// the descriptor.
string PROTOC_EXPORT EnumValueName(const EnumValueDescriptor* descriptor);
std::string PROTOC_EXPORT EnumValueName(const EnumValueDescriptor* descriptor);
// Returns the name of the enum value corresponding to the descriptor.
string PROTOC_EXPORT EnumValueShortName(const EnumValueDescriptor* descriptor);
std::string PROTOC_EXPORT EnumValueShortName(const EnumValueDescriptor* descriptor);
// Reverse what an enum does.
string PROTOC_EXPORT UnCamelCaseEnumShortName(const string& name);
std::string PROTOC_EXPORT UnCamelCaseEnumShortName(const std::string& name);
// Returns the name to use for the extension (used as the method off the file's
// Root class).
string PROTOC_EXPORT ExtensionMethodName(const FieldDescriptor* descriptor);
std::string PROTOC_EXPORT ExtensionMethodName(const FieldDescriptor* descriptor);
// Returns the transformed field name.
string PROTOC_EXPORT FieldName(const FieldDescriptor* field);
string PROTOC_EXPORT FieldNameCapitalized(const FieldDescriptor* field);
std::string PROTOC_EXPORT FieldName(const FieldDescriptor* field);
std::string PROTOC_EXPORT FieldNameCapitalized(const FieldDescriptor* field);
// Returns the transformed oneof name.
string PROTOC_EXPORT OneofEnumName(const OneofDescriptor* descriptor);
string PROTOC_EXPORT OneofName(const OneofDescriptor* descriptor);
string PROTOC_EXPORT OneofNameCapitalized(const OneofDescriptor* descriptor);
std::string PROTOC_EXPORT OneofEnumName(const OneofDescriptor* descriptor);
std::string PROTOC_EXPORT OneofName(const OneofDescriptor* descriptor);
std::string PROTOC_EXPORT OneofNameCapitalized(const OneofDescriptor* descriptor);
// Returns a symbol that can be used in C code to refer to an Objective C
// class without initializing the class.
string PROTOC_EXPORT ObjCClass(const string& class_name);
std::string PROTOC_EXPORT ObjCClass(const std::string& class_name);
// Declares an Objective C class without initializing the class so that it can
// be refrerred to by ObjCClass.
string PROTOC_EXPORT ObjCClassDeclaration(const string& class_name);
std::string PROTOC_EXPORT ObjCClassDeclaration(const std::string& class_name);
inline bool HasPreservingUnknownEnumSemantics(const FileDescriptor* file) {
return file->syntax() == FileDescriptor::SYNTAX_PROTO3;
@ -136,8 +136,8 @@ inline bool IsMapEntryMessage(const Descriptor* descriptor) {
}
// Reverse of the above.
string PROTOC_EXPORT UnCamelCaseFieldName(const string& name,
const FieldDescriptor* field);
std::string PROTOC_EXPORT UnCamelCaseFieldName(const std::string& name,
const FieldDescriptor* field);
enum ObjectiveCType {
OBJECTIVECTYPE_INT32,
@ -159,11 +159,11 @@ enum FlagType {
FLAGTYPE_FIELD
};
template<class TDescriptor>
string GetOptionalDeprecatedAttribute(
const TDescriptor* descriptor,
const FileDescriptor* file = NULL,
bool preSpace = true, bool postNewline = false) {
template <class TDescriptor>
std::string GetOptionalDeprecatedAttribute(const TDescriptor* descriptor,
const FileDescriptor* file = NULL,
bool preSpace = true,
bool postNewline = false) {
bool isDeprecated = descriptor->options().deprecated();
// The file is only passed when checking Messages & Enums, so those types
// get tagged. At the moment, it doesn't seem to make sense to tag every
@ -174,7 +174,7 @@ string GetOptionalDeprecatedAttribute(
isDeprecated = isFileLevelDeprecation;
}
if (isDeprecated) {
string message;
std::string message;
const FileDescriptor* sourceFile = descriptor->file();
if (isFileLevelDeprecation) {
message = sourceFile->name() + " is deprecated.";
@ -183,7 +183,7 @@ string GetOptionalDeprecatedAttribute(
sourceFile->name() + ").";
}
string result = string("GPB_DEPRECATED_MSG(\"") + message + "\")";
std::string result = std::string("GPB_DEPRECATED_MSG(\"") + message + "\")";
if (preSpace) {
result.insert(0, " ");
}
@ -196,7 +196,7 @@ string GetOptionalDeprecatedAttribute(
}
}
string PROTOC_EXPORT GetCapitalizedType(const FieldDescriptor* field);
std::string PROTOC_EXPORT GetCapitalizedType(const FieldDescriptor* field);
ObjectiveCType PROTOC_EXPORT
GetObjectiveCType(FieldDescriptor::Type field_type);
@ -208,25 +208,26 @@ inline ObjectiveCType GetObjectiveCType(const FieldDescriptor* field) {
bool PROTOC_EXPORT IsPrimitiveType(const FieldDescriptor* field);
bool PROTOC_EXPORT IsReferenceType(const FieldDescriptor* field);
string PROTOC_EXPORT GPBGenericValueFieldName(const FieldDescriptor* field);
string PROTOC_EXPORT DefaultValue(const FieldDescriptor* field);
std::string PROTOC_EXPORT
GPBGenericValueFieldName(const FieldDescriptor* field);
std::string PROTOC_EXPORT DefaultValue(const FieldDescriptor* field);
bool PROTOC_EXPORT HasNonZeroDefaultValue(const FieldDescriptor* field);
string PROTOC_EXPORT BuildFlagsString(const FlagType type,
const std::vector<string>& strings);
std::string PROTOC_EXPORT
BuildFlagsString(const FlagType type, const std::vector<std::string>& strings);
// Builds HeaderDoc/appledoc style comments out of the comments in the .proto
// file.
string PROTOC_EXPORT BuildCommentsString(const SourceLocation& location,
bool prefer_single_line);
std::string PROTOC_EXPORT BuildCommentsString(const SourceLocation& location,
bool prefer_single_line);
// The name the commonly used by the library when built as a framework.
// This lines up to the name used in the CocoaPod.
extern PROTOC_EXPORT const char* const ProtobufLibraryFrameworkName;
// Returns the CPP symbol name to use as the gate for framework style imports
// for the given framework name to use.
string PROTOC_EXPORT
ProtobufFrameworkImportSymbol(const string& framework_name);
std::string PROTOC_EXPORT
ProtobufFrameworkImportSymbol(const std::string& framework_name);
// Checks if the file is one of the proto's bundled with the library.
bool PROTOC_EXPORT
@ -235,9 +236,9 @@ IsProtobufLibraryBundledProtoFile(const FileDescriptor* file);
// Checks the prefix for the given files and outputs any warnings as needed. If
// there are flat out errors, then out_error is filled in with the first error
// and the result is false.
bool PROTOC_EXPORT
ValidateObjCClassPrefixes(const std::vector<const FileDescriptor*>& files,
const Options& generation_options, string* out_error);
bool PROTOC_EXPORT ValidateObjCClassPrefixes(
const std::vector<const FileDescriptor*>& files,
const Options& generation_options, std::string* out_error);
// Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform
// the input into the expected output.
@ -249,16 +250,16 @@ class PROTOC_EXPORT TextFormatDecodeData {
TextFormatDecodeData(const TextFormatDecodeData&) = delete;
TextFormatDecodeData& operator=(const TextFormatDecodeData&) = delete;
void AddString(int32 key, const string& input_for_decode,
const string& desired_output);
void AddString(int32 key, const std::string& input_for_decode,
const std::string& desired_output);
size_t num_entries() const { return entries_.size(); }
string Data() const;
std::string Data() const;
static string DecodeDataForString(const string& input_for_decode,
const string& desired_output);
static std::string DecodeDataForString(const std::string& input_for_decode,
const std::string& desired_output);
private:
typedef std::pair<int32, string> DataEntry;
typedef std::pair<int32, std::string> DataEntry;
std::vector<DataEntry> entries_;
};
@ -267,55 +268,55 @@ class PROTOC_EXPORT LineConsumer {
public:
LineConsumer();
virtual ~LineConsumer();
virtual bool ConsumeLine(const StringPiece& line, string* out_error) = 0;
virtual bool ConsumeLine(const StringPiece& line, std::string* out_error) = 0;
};
bool PROTOC_EXPORT ParseSimpleFile(const string& path,
bool PROTOC_EXPORT ParseSimpleFile(const std::string& path,
LineConsumer* line_consumer,
string* out_error);
std::string* out_error);
// Helper class for parsing framework import mappings and generating
// import statements.
class PROTOC_EXPORT ImportWriter {
public:
ImportWriter(const string& generate_for_named_framework,
const string& named_framework_to_proto_path_mappings_path,
const string& runtime_import_prefix,
ImportWriter(const std::string& generate_for_named_framework,
const std::string& named_framework_to_proto_path_mappings_path,
const std::string& runtime_import_prefix,
bool include_wkt_imports);
~ImportWriter();
void AddFile(const FileDescriptor* file, const string& header_extension);
void AddFile(const FileDescriptor* file, const std::string& header_extension);
void Print(io::Printer *printer) const;
static void PrintRuntimeImports(io::Printer *printer,
const std::vector<string>& header_to_import,
const string& runtime_import_prefix,
const std::vector<std::string>& header_to_import,
const std::string& runtime_import_prefix,
bool default_cpp_symbol = false);
private:
class ProtoFrameworkCollector : public LineConsumer {
public:
ProtoFrameworkCollector(std::map<string, string>* inout_proto_file_to_framework_name)
ProtoFrameworkCollector(std::map<std::string, std::string>* inout_proto_file_to_framework_name)
: map_(inout_proto_file_to_framework_name) {}
virtual bool ConsumeLine(const StringPiece& line, string* out_error);
virtual bool ConsumeLine(const StringPiece& line, std::string* out_error);
private:
std::map<string, string>* map_;
std::map<std::string, std::string>* map_;
};
void ParseFrameworkMappings();
const string generate_for_named_framework_;
const string named_framework_to_proto_path_mappings_path_;
const string runtime_import_prefix_;
const std::string generate_for_named_framework_;
const std::string named_framework_to_proto_path_mappings_path_;
const std::string runtime_import_prefix_;
const bool include_wkt_imports_;
std::map<string, string> proto_file_to_framework_name_;
std::map<std::string, std::string> proto_file_to_framework_name_;
bool need_to_parse_mapping_file_;
std::vector<string> protobuf_imports_;
std::vector<string> other_framework_imports_;
std::vector<string> other_imports_;
std::vector<std::string> protobuf_imports_;
std::vector<std::string> other_framework_imports_;
std::vector<std::string> other_imports_;
};
} // namespace objectivec

@ -39,21 +39,21 @@ namespace objectivec {
namespace {
TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_RawStrings) {
string input_for_decode("abcdefghIJ");
string desired_output_for_decode;
string expected;
string result;
std::string input_for_decode("abcdefghIJ");
std::string desired_output_for_decode;
std::string expected;
std::string result;
// Different data, can't transform.
desired_output_for_decode = "zbcdefghIJ";
expected = string("\0zbcdefghIJ\0", 12);
expected = std::string("\0zbcdefghIJ\0", 12);
result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
desired_output_for_decode);
EXPECT_EQ(expected, result);
desired_output_for_decode = "abcdezghIJ";
expected = string("\0abcdezghIJ\0", 12);
expected = std::string("\0abcdezghIJ\0", 12);
result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
desired_output_for_decode);
EXPECT_EQ(expected, result);
@ -61,7 +61,7 @@ TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_RawStrings) {
// Shortened data, can't transform.
desired_output_for_decode = "abcdefghI";
expected = string("\0abcdefghI\0", 11);
expected = std::string("\0abcdefghI\0", 11);
result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
desired_output_for_decode);
EXPECT_EQ(expected, result);
@ -69,32 +69,32 @@ TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_RawStrings) {
// Extra data, can't transform.
desired_output_for_decode = "abcdefghIJz";
expected = string("\0abcdefghIJz\0", 13);
expected = std::string("\0abcdefghIJz\0", 13);
result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
desired_output_for_decode);
EXPECT_EQ(expected, result);
}
TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_ByteCodes) {
string input_for_decode("abcdefghIJ");
string desired_output_for_decode;
string expected;
string result;
std::string input_for_decode("abcdefghIJ");
std::string desired_output_for_decode;
std::string expected;
std::string result;
desired_output_for_decode = "abcdefghIJ";
expected = string("\x0A\x0", 2);
expected = std::string("\x0A\x0", 2);
result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
desired_output_for_decode);
EXPECT_EQ(expected, result);
desired_output_for_decode = "_AbcdefghIJ";
expected = string("\xCA\x0", 2);
expected = std::string("\xCA\x0", 2);
result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
desired_output_for_decode);
EXPECT_EQ(expected, result);
desired_output_for_decode = "ABCD__EfghI_j";
expected = string("\x64\x80\xC5\xA1\x0", 5);
expected = std::string("\x64\x80\xC5\xA1\x0", 5);
result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
desired_output_for_decode);
EXPECT_EQ(expected, result);
@ -105,7 +105,7 @@ TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_ByteCodes) {
"longFieldNameIsLooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong1000";
desired_output_for_decode =
"long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1000";
expected = string("\x04\xA5\xA4\xA2\xBF\x1F\x0E\x84\x0", 9);
expected = std::string("\x04\xA5\xA4\xA2\xBF\x1F\x0E\x84\x0", 9);
result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
desired_output_for_decode);
EXPECT_EQ(expected, result);
@ -128,7 +128,7 @@ TEST(ObjCHelperDeathTest, TextFormatDecodeData_DecodeDataForString_Failures) {
// Null char in the string.
string str_with_null_char("ab\0c", 4);
std::string str_with_null_char("ab\0c", 4);
EXPECT_EXIT(
TextFormatDecodeData::DecodeDataForString(str_with_null_char, "def"),
::testing::KilledBySignal(SIGABRT),
@ -160,7 +160,7 @@ TEST(ObjCHelper, TextFormatDecodeData_RawStrings) {
0x2, 0x0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'I', 0x0,
0x4, 0x0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'I', 'J', 'z', 0x0,
};
string expected((const char*)expected_data, sizeof(expected_data));
std::string expected((const char*)expected_data, sizeof(expected_data));
EXPECT_EQ(expected, decode_data.Data());
}
@ -196,7 +196,7 @@ TEST(ObjCHelper, TextFormatDecodeData_ByteCodes) {
// underscore, as is + 3 (00 op)
0xE8, 0x07, 0x04, 0xA5, 0xA4, 0xA2, 0xBF, 0x1F, 0x0E, 0x84, 0x0,
};
string expected((const char*)expected_data, sizeof(expected_data));
std::string expected((const char*)expected_data, sizeof(expected_data));
EXPECT_EQ(expected, decode_data.Data());
}
@ -221,7 +221,7 @@ TEST(ObjCHelperDeathTest, TextFormatDecodeData_Failures) {
// Null char in the string.
string str_with_null_char("ab\0c", 4);
std::string str_with_null_char("ab\0c", 4);
EXPECT_EXIT(
decode_data.AddString(1, str_with_null_char, "def"),
::testing::KilledBySignal(SIGABRT),

@ -96,20 +96,21 @@ MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor,
variables_["default_name"] = value_field_generator_->variable("default_name");
// Build custom field flags.
std::vector<string> field_flags;
std::vector<std::string> field_flags;
field_flags.push_back("GPBFieldMapKey" + GetCapitalizedType(key_descriptor));
// Pull over the current text format custom name values that was calculated.
if (variables_["fieldflags"].find("GPBFieldTextFormatNameCustom") !=
string::npos) {
std::string::npos) {
field_flags.push_back("GPBFieldTextFormatNameCustom");
}
// Pull over some info from the value's flags.
const string& value_field_flags =
const std::string& value_field_flags =
value_field_generator_->variable("fieldflags");
if (value_field_flags.find("GPBFieldHasDefaultValue") != string::npos) {
if (value_field_flags.find("GPBFieldHasDefaultValue") != std::string::npos) {
field_flags.push_back("GPBFieldHasDefaultValue");
}
if (value_field_flags.find("GPBFieldHasEnumDescriptor") != string::npos) {
if (value_field_flags.find("GPBFieldHasEnumDescriptor") !=
std::string::npos) {
field_flags.push_back("GPBFieldHasEnumDescriptor");
}
@ -127,7 +128,7 @@ MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor,
"NSMutableDictionary<NSString*, " +
value_field_generator_->variable("storage_type") + "*>";
} else {
string class_name("GPB");
std::string class_name("GPB");
class_name += MapEntryTypeName(key_descriptor, true);
class_name += MapEntryTypeName(value_descriptor, false);
class_name += "Dictionary";
@ -160,19 +161,19 @@ void MapFieldGenerator::FinishInitialization(void) {
}
void MapFieldGenerator::DetermineForwardDeclarations(
std::set<string>* fwd_decls) const {
std::set<std::string>* fwd_decls) const {
RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls);
const FieldDescriptor* value_descriptor =
descriptor_->message_type()->FindFieldByName("value");
if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE) {
const string& value_storage_type =
const std::string& value_storage_type =
value_field_generator_->variable("storage_type");
fwd_decls->insert("@class " + value_storage_type);
}
}
void MapFieldGenerator::DetermineObjectiveCClassDefinitions(
std::set<string>* fwd_decls) const {
std::set<std::string>* fwd_decls) const {
// Class name is already in "storage_type".
const FieldDescriptor* value_descriptor =
descriptor_->message_type()->FindFieldByName("value");
@ -182,7 +183,6 @@ void MapFieldGenerator::DetermineObjectiveCClassDefinitions(
}
}
} // namespace objectivec
} // namespace compiler
} // namespace protobuf

@ -54,8 +54,10 @@ class MapFieldGenerator : public RepeatedFieldGenerator {
MapFieldGenerator(const FieldDescriptor* descriptor, const Options& options);
virtual ~MapFieldGenerator();
virtual void DetermineObjectiveCClassDefinitions(std::set<string>* fwd_decls) const;
virtual void DetermineForwardDeclarations(std::set<string>* fwd_decls) const;
virtual void DetermineObjectiveCClassDefinitions(
std::set<std::string>* fwd_decls) const;
virtual void DetermineForwardDeclarations(
std::set<std::string>* fwd_decls) const;
private:
std::unique_ptr<FieldGenerator> value_field_generator_;

@ -170,16 +170,15 @@ const FieldDescriptor** SortFieldsByStorageSize(const Descriptor* descriptor) {
}
} // namespace
MessageGenerator::MessageGenerator(const string& root_classname,
MessageGenerator::MessageGenerator(const std::string& root_classname,
const Descriptor* descriptor,
const Options& options)
: root_classname_(root_classname),
descriptor_(descriptor),
field_generators_(descriptor, options),
class_name_(ClassName(descriptor_)),
deprecated_attribute_(
GetOptionalDeprecatedAttribute(descriptor, descriptor->file(), false, true)) {
deprecated_attribute_(GetOptionalDeprecatedAttribute(
descriptor, descriptor->file(), false, true)) {
for (int i = 0; i < descriptor_->extension_count(); i++) {
extension_generators_.emplace_back(
new ExtensionGenerator(class_name_, descriptor_->extension(i)));
@ -217,7 +216,8 @@ void MessageGenerator::GenerateStaticVariablesInitialization(
}
}
void MessageGenerator::DetermineForwardDeclarations(std::set<string>* fwd_decls) {
void MessageGenerator::DetermineForwardDeclarations(
std::set<std::string>* fwd_decls) {
if (!IsMapEntryMessage(descriptor_)) {
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* fieldDescriptor = descriptor_->field(i);
@ -231,7 +231,8 @@ void MessageGenerator::DetermineForwardDeclarations(std::set<string>* fwd_decls)
}
}
void MessageGenerator::DetermineObjectiveCClassDefinitions(std::set<string>* fwd_decls) {
void MessageGenerator::DetermineObjectiveCClassDefinitions(
std::set<std::string>* fwd_decls) {
if (!IsMapEntryMessage(descriptor_)) {
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* fieldDescriptor = descriptor_->field(i);
@ -250,7 +251,7 @@ void MessageGenerator::DetermineObjectiveCClassDefinitions(std::set<string>* fwd
const Descriptor* containing_descriptor = descriptor_->containing_type();
if (containing_descriptor != NULL) {
string containing_class = ClassName(containing_descriptor);
std::string containing_class = ClassName(containing_descriptor);
fwd_decls->insert(ObjCClassDeclaration(containing_class));
}
}
@ -325,7 +326,7 @@ void MessageGenerator::GenerateMessageHeader(io::Printer* printer) {
generator->GenerateCaseEnum(printer);
}
string message_comments;
std::string message_comments;
SourceLocation location;
if (descriptor_->GetSourceLocation(&location)) {
message_comments = BuildCommentsString(location, false);
@ -473,7 +474,7 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
TextFormatDecodeData text_format_decode_data;
bool has_fields = descriptor_->field_count() > 0;
bool need_defaults = field_generators_.DoesAnyFieldHaveNonZeroDefault();
string field_description_type;
std::string field_description_type;
if (need_defaults) {
field_description_type = "GPBMessageFieldDescriptionWithDefault";
} else {
@ -503,7 +504,7 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
printer->Outdent();
}
std::map<string, string> vars;
std::map<std::string, std::string> vars;
vars["classname"] = class_name_;
vars["rootclassname"] = root_classname_;
vars["fields"] = has_fields ? "fields" : "NULL";
@ -514,7 +515,7 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
vars["fields_count"] = "0";
}
std::vector<string> init_flags;
std::vector<std::string> init_flags;
init_flags.push_back("GPBDescriptorInitializationFlag_UsesClassRefs");
init_flags.push_back("GPBDescriptorInitializationFlag_Proto3OptionalKnown");
if (need_defaults) {
@ -551,7 +552,7 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
"first_has_index", oneof_generators_[0]->HasIndexAsString());
}
if (text_format_decode_data.num_entries() != 0) {
const string text_format_data_str(text_format_decode_data.Data());
const std::string text_format_data_str(text_format_decode_data.Data());
printer->Print(
"#if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS\n"
" static const char *extraTextFormatInfo =");
@ -581,13 +582,13 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
" count:(uint32_t)(sizeof(ranges) / sizeof(GPBExtensionRange))];\n");
}
if (descriptor_->containing_type() != NULL) {
string containing_class = ClassName(descriptor_->containing_type());
string parent_class_ref = ObjCClass(containing_class);
std::string containing_class = ClassName(descriptor_->containing_type());
std::string parent_class_ref = ObjCClass(containing_class);
printer->Print(
" [localDescriptor setupContainingMessageClass:$parent_class_ref$];\n",
"parent_class_ref", parent_class_ref);
}
string suffix_added;
std::string suffix_added;
ClassName(descriptor_, &suffix_added);
if (!suffix_added.empty()) {
printer->Print(

@ -50,9 +50,8 @@ class EnumGenerator;
class MessageGenerator {
public:
MessageGenerator(const string& root_classname,
const Descriptor* descriptor,
const Options& options);
MessageGenerator(const std::string& root_classname,
const Descriptor* descriptor, const Options& options);
~MessageGenerator();
MessageGenerator(const MessageGenerator&) = delete;
@ -63,8 +62,8 @@ class MessageGenerator {
void GenerateMessageHeader(io::Printer* printer);
void GenerateSource(io::Printer* printer);
void GenerateExtensionRegistrationSource(io::Printer* printer);
void DetermineObjectiveCClassDefinitions(std::set<string>* fwd_decls);
void DetermineForwardDeclarations(std::set<string>* fwd_decls);
void DetermineObjectiveCClassDefinitions(std::set<std::string>* fwd_decls);
void DetermineForwardDeclarations(std::set<std::string>* fwd_decls);
// Checks if the message or a nested message includes a oneof definition.
bool IncludesOneOfDefinition() const;
@ -81,11 +80,11 @@ class MessageGenerator {
void GenerateDescriptionOneFieldSource(io::Printer* printer,
const FieldDescriptor* field);
const string root_classname_;
const std::string root_classname_;
const Descriptor* descriptor_;
FieldGeneratorMap field_generators_;
const string class_name_;
const string deprecated_attribute_;
const std::string class_name_;
const std::string deprecated_attribute_;
std::vector<std::unique_ptr<ExtensionGenerator>> extension_generators_;
std::vector<std::unique_ptr<EnumGenerator>> enum_generators_;
std::vector<std::unique_ptr<MessageGenerator>> nested_message_generators_;

@ -44,9 +44,10 @@ namespace objectivec {
namespace {
void SetMessageVariables(const FieldDescriptor* descriptor,
std::map<string, string>* variables) {
const string& message_type = ClassName(descriptor->message_type());
const string& containing_class = ClassName(descriptor->containing_type());
std::map<std::string, std::string>* variables) {
const std::string& message_type = ClassName(descriptor->message_type());
const std::string& containing_class =
ClassName(descriptor->containing_type());
(*variables)["type"] = message_type;
(*variables)["containing_class"] = containing_class;
(*variables)["storage_type"] = message_type;
@ -66,14 +67,14 @@ MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor,
MessageFieldGenerator::~MessageFieldGenerator() {}
void MessageFieldGenerator::DetermineForwardDeclarations(
std::set<string>* fwd_decls) const {
std::set<std::string>* fwd_decls) const {
ObjCObjFieldGenerator::DetermineForwardDeclarations(fwd_decls);
// Class name is already in "storage_type".
fwd_decls->insert("@class " + variable("storage_type"));
}
void MessageFieldGenerator::DetermineObjectiveCClassDefinitions(
std::set<string>* fwd_decls) const {
std::set<std::string>* fwd_decls) const {
fwd_decls->insert(ObjCClassDeclaration(variable("storage_type")));
}
@ -89,14 +90,14 @@ RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
void RepeatedMessageFieldGenerator::DetermineForwardDeclarations(
std::set<string>* fwd_decls) const {
std::set<std::string>* fwd_decls) const {
RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls);
// Class name is already in "storage_type".
fwd_decls->insert("@class " + variable("storage_type"));
}
void RepeatedMessageFieldGenerator::DetermineObjectiveCClassDefinitions(
std::set<string>* fwd_decls) const {
std::set<std::string>* fwd_decls) const {
fwd_decls->insert(ObjCClassDeclaration(variable("storage_type")));
}

@ -54,8 +54,10 @@ class MessageFieldGenerator : public ObjCObjFieldGenerator {
virtual ~MessageFieldGenerator();
public:
virtual void DetermineForwardDeclarations(std::set<string>* fwd_decls) const;
virtual void DetermineObjectiveCClassDefinitions(std::set<string>* fwd_decls) const;
virtual void DetermineForwardDeclarations(
std::set<std::string>* fwd_decls) const;
virtual void DetermineObjectiveCClassDefinitions(
std::set<std::string>* fwd_decls) const;
};
class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator {
@ -71,8 +73,10 @@ class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator {
RepeatedMessageFieldGenerator operator=(const RepeatedMessageFieldGenerator&) = delete;
public:
virtual void DetermineForwardDeclarations(std::set<string>* fwd_decls) const;
virtual void DetermineObjectiveCClassDefinitions(std::set<string>* fwd_decls) const;
virtual void DetermineForwardDeclarations(
std::set<std::string>* fwd_decls) const;
virtual void DetermineObjectiveCClassDefinitions(
std::set<std::string>* fwd_decls) const;
};
} // namespace objectivec

@ -50,7 +50,7 @@ OneofGenerator::OneofGenerator(const OneofDescriptor* descriptor)
const Descriptor* msg_descriptor = descriptor_->containing_type();
variables_["owning_message_class"] = ClassName(msg_descriptor);
string comments;
std::string comments;
SourceLocation location;
if (descriptor_->GetSourceLocation(&location)) {
comments = BuildCommentsString(location, true);
@ -76,10 +76,10 @@ void OneofGenerator::GenerateCaseEnum(io::Printer* printer) {
printer->Print(
variables_,
"$enum_name$_GPBUnsetOneOfCase = 0,\n");
string enum_name = variables_["enum_name"];
std::string enum_name = variables_["enum_name"];
for (int j = 0; j < descriptor_->field_count(); j++) {
const FieldDescriptor* field = descriptor_->field(j);
string field_name = FieldNameCapitalized(field);
std::string field_name = FieldNameCapitalized(field);
printer->Print(
"$enum_name$_$field_name$ = $field_number$,\n",
"enum_name", enum_name,
@ -126,11 +126,11 @@ void OneofGenerator::GenerateClearFunctionImplementation(io::Printer* printer) {
"}\n");
}
string OneofGenerator::DescriptorName(void) const {
std::string OneofGenerator::DescriptorName(void) const {
return variables_.find("name")->second;
}
string OneofGenerator::HasIndexAsString(void) const {
std::string OneofGenerator::HasIndexAsString(void) const {
return variables_.find("index")->second;
}

@ -60,12 +60,12 @@ class OneofGenerator {
void GeneratePropertyImplementation(io::Printer* printer);
void GenerateClearFunctionImplementation(io::Printer* printer);
string DescriptorName(void) const;
string HasIndexAsString(void) const;
std::string DescriptorName(void) const;
std::string HasIndexAsString(void) const;
private:
const OneofDescriptor* descriptor_;
std::map<string, string> variables_;
std::map<std::string, std::string> variables_;
};
} // namespace objectivec

@ -116,7 +116,7 @@ const char* PrimitiveArrayTypeName(const FieldDescriptor* descriptor) {
}
void SetPrimitiveVariables(const FieldDescriptor* descriptor,
std::map<string, string>* variables) {
std::map<std::string, std::string>* variables) {
std::string primitive_name = PrimitiveTypeName(descriptor);
(*variables)["type"] = primitive_name;
(*variables)["storage_type"] = primitive_name;
@ -172,7 +172,7 @@ RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator(
: RepeatedFieldGenerator(descriptor, options) {
SetPrimitiveVariables(descriptor, &variables_);
string base_name = PrimitiveArrayTypeName(descriptor);
std::string base_name = PrimitiveArrayTypeName(descriptor);
if (base_name.length()) {
variables_["array_storage_type"] = "GPB" + base_name + "Array";
} else {

@ -82,18 +82,20 @@ namespace php {
std::string PhpName(const std::string& full_name, bool is_descriptor);
std::string DefaultForField(FieldDescriptor* field);
std::string IntToString(int32 value);
std::string FilenameToClassname(const string& filename);
std::string FilenameToClassname(const std::string& filename);
std::string GeneratedMetadataFileName(const FileDescriptor* file,
bool is_descriptor);
std::string LabelForField(FieldDescriptor* field);
std::string TypeName(FieldDescriptor* field);
std::string UnderscoresToCamelCase(const string& name, bool cap_first_letter);
std::string BinaryToHex(const string& binary);
std::string UnderscoresToCamelCase(const std::string& name,
bool cap_first_letter);
std::string BinaryToHex(const std::string& binary);
void Indent(io::Printer* printer);
void Outdent(io::Printer* printer);
void GenerateAddFilesToPool(const FileDescriptor* file,
const std::set<string>& aggregate_metadata_prefixes,
io::Printer* printer);
void GenerateAddFilesToPool(
const FileDescriptor* file,
const std::set<std::string>& aggregate_metadata_prefixes,
io::Printer* printer);
void GenerateMessageDocComment(io::Printer* printer, const Descriptor* message,
int is_descriptor);
void GenerateMessageConstructorDocComment(io::Printer* printer,
@ -114,11 +116,11 @@ void GenerateServiceDocComment(io::Printer* printer,
void GenerateServiceMethodDocComment(io::Printer* printer,
const MethodDescriptor* method);
std::string ReservedNamePrefix(const string& classname,
std::string ReservedNamePrefix(const std::string& classname,
const FileDescriptor* file) {
bool is_reserved = false;
string lower = classname;
std::string lower = classname;
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
for (int i = 0; i < kReservedNamesSize; i++) {
@ -151,9 +153,9 @@ std::string DescriptorFullName(const DescriptorType* desc, bool is_descriptor) {
}
template <typename DescriptorType>
std::string ClassNamePrefix(const string& classname,
std::string ClassNamePrefix(const std::string& classname,
const DescriptorType* desc) {
const string& prefix = (desc->file()->options()).php_class_prefix();
const std::string& prefix = (desc->file()->options()).php_class_prefix();
if (!prefix.empty()) {
return prefix;
}
@ -201,8 +203,8 @@ std::string LegacyGeneratedClassName(const DescriptorType* desc) {
return ClassNamePrefix(classname, desc) + classname;
}
std::string ClassNamePrefix(const string& classname) {
string lower = classname;
std::string ClassNamePrefix(const std::string& classname) {
std::string lower = classname;
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
for (int i = 0; i < kReservedNamesSize; i++) {
@ -214,10 +216,10 @@ std::string ClassNamePrefix(const string& classname) {
return "";
}
std::string ConstantNamePrefix(const string& classname) {
std::string ConstantNamePrefix(const std::string& classname) {
bool is_reserved = false;
string lower = classname;
std::string lower = classname;
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
for (int i = 0; i < kReservedNamesSize; i++) {
@ -244,7 +246,7 @@ std::string ConstantNamePrefix(const string& classname) {
template <typename DescriptorType>
std::string RootPhpNamespace(const DescriptorType* desc, bool is_descriptor) {
if (desc->file()->options().has_php_namespace()) {
const string& php_namespace = desc->file()->options().php_namespace();
const std::string& php_namespace = desc->file()->options().php_namespace();
if (!php_namespace.empty()) {
return php_namespace;
}
@ -259,8 +261,8 @@ std::string RootPhpNamespace(const DescriptorType* desc, bool is_descriptor) {
template <typename DescriptorType>
std::string FullClassName(const DescriptorType* desc, bool is_descriptor) {
string classname = GeneratedClassNameImpl(desc);
string php_namespace = RootPhpNamespace(desc, is_descriptor);
std::string classname = GeneratedClassNameImpl(desc);
std::string php_namespace = RootPhpNamespace(desc, is_descriptor);
if (!php_namespace.empty()) {
return php_namespace + "\\" + classname;
}
@ -269,8 +271,8 @@ std::string FullClassName(const DescriptorType* desc, bool is_descriptor) {
template <typename DescriptorType>
std::string LegacyFullClassName(const DescriptorType* desc, bool is_descriptor) {
string classname = LegacyGeneratedClassName(desc);
string php_namespace = RootPhpNamespace(desc, is_descriptor);
std::string classname = LegacyGeneratedClassName(desc);
std::string php_namespace = RootPhpNamespace(desc, is_descriptor);
if (!php_namespace.empty()) {
return php_namespace + "\\" + classname;
}
@ -328,7 +330,7 @@ std::string DefaultForField(const FieldDescriptor* field) {
std::string GeneratedMetadataFileName(const FileDescriptor* file,
bool is_descriptor) {
const string& proto_file = file->name();
const std::string& proto_file = file->name();
int start_index = 0;
int first_index = proto_file.find_first_of("/", start_index);
std::string result = "";
@ -351,7 +353,7 @@ std::string GeneratedMetadataFileName(const FileDescriptor* file,
}
if (file->options().has_php_metadata_namespace()) {
const string& php_metadata_namespace =
const std::string& php_metadata_namespace =
file->options().php_metadata_namespace();
if (!php_metadata_namespace.empty() && php_metadata_namespace != "\\") {
result += php_metadata_namespace;
@ -362,7 +364,7 @@ std::string GeneratedMetadataFileName(const FileDescriptor* file,
}
} else {
result += "GPBMetadata/";
while (first_index != string::npos) {
while (first_index != std::string::npos) {
segment = UnderscoresToCamelCase(
file_no_suffix.substr(start_index, first_index - start_index), true);
result += ReservedNamePrefix(segment, file) + segment + "/";
@ -373,7 +375,7 @@ std::string GeneratedMetadataFileName(const FileDescriptor* file,
// Append file name.
int file_name_start = file_no_suffix.find_last_of("/");
if (file_name_start == string::npos) {
if (file_name_start == std::string::npos) {
file_name_start = 0;
} else {
file_name_start += 1;
@ -463,7 +465,7 @@ std::string PhpSetterTypeName(const FieldDescriptor* field, bool is_descriptor)
if (field->is_map()) {
return "array|\\Google\\Protobuf\\Internal\\MapField";
}
string type;
std::string type;
switch (field->type()) {
case FieldDescriptor::TYPE_INT32:
case FieldDescriptor::TYPE_UINT32:
@ -553,7 +555,8 @@ std::string EnumOrMessageSuffix(
// Converts a name to camel-case. If cap_first_letter is true, capitalize the
// first letter.
std::string UnderscoresToCamelCase(const string& name, bool cap_first_letter) {
std::string UnderscoresToCamelCase(const std::string& name,
bool cap_first_letter) {
std::string result;
for (int i = 0; i < name.size(); i++) {
if ('a' <= name[i] && name[i] <= 'z') {
@ -587,8 +590,8 @@ std::string UnderscoresToCamelCase(const string& name, bool cap_first_letter) {
return result;
}
std::string BinaryToHex(const string& binary) {
string dest;
std::string BinaryToHex(const std::string& binary) {
std::string dest;
size_t i;
unsigned char symbol[16] = {
'0', '1', '2', '3',
@ -844,15 +847,16 @@ void GenerateServiceMethod(const MethodDescriptor* method,
);
}
void GenerateMessageToPool(const string& name_prefix, const Descriptor* message,
io::Printer* printer) {
void GenerateMessageToPool(const std::string& name_prefix,
const Descriptor* message, io::Printer* printer) {
// Don't generate MapEntry messages -- we use the PHP extension's native
// support for map fields instead.
if (message->options().map_entry()) {
return;
}
string class_name = (name_prefix.empty() ? "" : name_prefix + "\\") +
ReservedNamePrefix(message->name(), message->file()) + message->name();
std::string class_name =
(name_prefix.empty() ? "" : name_prefix + "\\") +
ReservedNamePrefix(message->name(), message->file()) + message->name();
printer->Print(
"$pool->addMessage('^message^', "
@ -926,10 +930,8 @@ void GenerateMessageToPool(const string& name_prefix, const Descriptor* message,
}
void GenerateAddFileToPool(
const FileDescriptor* file,
bool is_descriptor,
bool aggregate_metadata,
const std::set<string>& aggregate_metadata_prefixes,
const FileDescriptor* file, bool is_descriptor, bool aggregate_metadata,
const std::set<std::string>& aggregate_metadata_prefixes,
io::Printer* printer) {
printer->Print(
"public static $is_initialized = false;\n\n"
@ -978,8 +980,9 @@ void GenerateAddFileToPool(
file->CopyTo(file_proto);
// Filter out descriptor.proto as it cannot be depended on for now.
RepeatedPtrField<string>* dependency = file_proto->mutable_dependency();
for (RepeatedPtrField<string>::iterator it = dependency->begin();
RepeatedPtrField<std::string>* dependency =
file_proto->mutable_dependency();
for (RepeatedPtrField<std::string>::iterator it = dependency->begin();
it != dependency->end(); ++it) {
if (*it != kDescriptorFile) {
dependency->erase(it);
@ -996,7 +999,7 @@ void GenerateAddFileToPool(
it->clear_extension();
}
string files_data;
std::string files_data;
files.SerializeToString(&files_data);
printer->Print("$pool->internalAddGeneratedFile(hex2bin(\n");
@ -1053,7 +1056,7 @@ static void AnalyzeDependencyForFile(
static bool NeedsUnwrapping(
const FileDescriptor* file,
const std::set<string>& aggregate_metadata_prefixes) {
const std::set<std::string>& aggregate_metadata_prefixes) {
bool has_aggregate_metadata_prefix = false;
if (aggregate_metadata_prefixes.empty()) {
has_aggregate_metadata_prefix = true;
@ -1071,7 +1074,7 @@ static bool NeedsUnwrapping(
void GenerateAddFilesToPool(
const FileDescriptor* file,
const std::set<string>& aggregate_metadata_prefixes,
const std::set<std::string>& aggregate_metadata_prefixes,
io::Printer* printer) {
printer->Print(
"$pool = \\Google\\Protobuf\\Internal\\"
@ -1108,8 +1111,9 @@ void GenerateAddFilesToPool(
file->CopyTo(file_proto);
// Filter out descriptor.proto as it cannot be depended on for now.
RepeatedPtrField<string>* dependency = file_proto->mutable_dependency();
for (RepeatedPtrField<string>::iterator it = dependency->begin();
RepeatedPtrField<std::string>* dependency =
file_proto->mutable_dependency();
for (RepeatedPtrField<std::string>::iterator it = dependency->begin();
it != dependency->end(); ++it) {
if (*it != kDescriptorFile) {
dependency->erase(it);
@ -1134,7 +1138,7 @@ void GenerateAddFilesToPool(
}
}
string files_data;
std::string files_data;
sorted_file_set.SerializeToString(&files_data);
printer->Print("$pool->internalAddGeneratedFile(hex2bin(\n");
@ -1177,7 +1181,7 @@ void GenerateHead(const FileDescriptor* file, io::Printer* printer) {
"filename", file->name());
}
std::string FilenameToClassname(const string& filename) {
std::string FilenameToClassname(const std::string& filename) {
int lastindex = filename.find_last_of(".");
std::string result = filename.substr(0, lastindex);
for (int i = 0; i < result.size(); i++) {
@ -1188,11 +1192,10 @@ std::string FilenameToClassname(const string& filename) {
return result;
}
void GenerateMetadataFile(const FileDescriptor* file,
bool is_descriptor,
bool aggregate_metadata,
const std::set<string>& aggregate_metadata_prefixes,
GeneratorContext* generator_context) {
void GenerateMetadataFile(
const FileDescriptor* file, bool is_descriptor, bool aggregate_metadata,
const std::set<std::string>& aggregate_metadata_prefixes,
GeneratorContext* generator_context) {
std::string filename = GeneratedMetadataFileName(file, is_descriptor);
std::unique_ptr<io::ZeroCopyOutputStream> output(
generator_context->Open(filename));
@ -1203,7 +1206,7 @@ void GenerateMetadataFile(const FileDescriptor* file,
std::string fullname = FilenameToClassname(filename);
int lastindex = fullname.find_last_of("\\");
if (lastindex != string::npos) {
if (lastindex != std::string::npos) {
printer.Print(
"namespace ^name^;\n\n",
"name", fullname.substr(0, lastindex));
@ -1277,7 +1280,7 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en,
std::string fullname = FilenameToClassname(filename);
int lastindex = fullname.find_last_of("\\");
if (lastindex != string::npos) {
if (lastindex != std::string::npos) {
printer.Print(
"namespace ^name^;\n\n",
"name", fullname.substr(0, lastindex));
@ -1289,7 +1292,7 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en,
GenerateEnumDocComment(&printer, en, is_descriptor);
if (lastindex != string::npos) {
if (lastindex != std::string::npos) {
fullname = fullname.substr(lastindex + 1);
}
@ -1389,7 +1392,7 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message,
std::string fullname = FilenameToClassname(filename);
int lastindex = fullname.find_last_of("\\");
if (lastindex != string::npos) {
if (lastindex != std::string::npos) {
printer.Print(
"namespace ^name^;\n\n",
"name", fullname.substr(0, lastindex));
@ -1398,7 +1401,7 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message,
GenerateUseDeclaration(is_descriptor, &printer);
GenerateMessageDocComment(&printer, message, is_descriptor);
if (lastindex != string::npos) {
if (lastindex != std::string::npos) {
fullname = fullname.substr(lastindex + 1);
}
@ -1497,7 +1500,7 @@ void GenerateServiceFile(const FileDescriptor* file,
if (!file->options().php_namespace().empty() ||
(!file->options().has_php_namespace() && !file->package().empty()) ||
lastindex != string::npos) {
lastindex != std::string::npos) {
printer.Print(
"namespace ^name^;\n\n",
"name", fullname.substr(0, lastindex));
@ -1505,13 +1508,13 @@ void GenerateServiceFile(const FileDescriptor* file,
GenerateServiceDocComment(&printer, service);
if (lastindex != string::npos) {
printer.Print(
if (lastindex != std::string::npos) {
printer.Print(
"interface ^name^\n"
"{\n",
"name", fullname.substr(lastindex + 1));
} else {
printer.Print(
printer.Print(
"interface ^name^\n"
"{\n",
"name", fullname);
@ -1531,7 +1534,7 @@ void GenerateServiceFile(const FileDescriptor* file,
void GenerateFile(const FileDescriptor* file, bool is_descriptor,
bool aggregate_metadata,
const std::set<string>& aggregate_metadata_prefixes,
const std::set<std::string>& aggregate_metadata_prefixes,
GeneratorContext* generator_context) {
GenerateMetadataFile(file, is_descriptor, aggregate_metadata,
aggregate_metadata_prefixes, generator_context);
@ -1553,13 +1556,13 @@ void GenerateFile(const FileDescriptor* file, bool is_descriptor,
}
}
static string EscapePhpdoc(const string& input) {
string result;
static std::string EscapePhpdoc(const std::string& input) {
std::string result;
result.reserve(input.size() * 2);
char prev = '*';
for (string::size_type i = 0; i < input.size(); i++) {
for (std::string::size_type i = 0; i < input.size(); i++) {
char c = input[i];
switch (c) {
case '*':
@ -1598,8 +1601,9 @@ static string EscapePhpdoc(const string& input) {
static void GenerateDocCommentBodyForLocation(
io::Printer* printer, const SourceLocation& location, bool trailingNewline,
int indentCount) {
string comments = location.leading_comments.empty() ?
location.trailing_comments : location.leading_comments;
std::string comments = location.leading_comments.empty()
? location.trailing_comments
: location.leading_comments;
if (!comments.empty()) {
// TODO(teboring): Ideally we should parse the comment text as Markdown and
// write it back as HTML, but this requires a Markdown parser. For now
@ -1609,7 +1613,7 @@ static void GenerateDocCommentBodyForLocation(
// HTML-escape them so that they don't accidentally close the doc comment.
comments = EscapePhpdoc(comments);
std::vector<string> lines = Split(comments, "\n", true);
std::vector<std::string> lines = Split(comments, "\n", true);
while (!lines.empty() && lines.back().empty()) {
lines.pop_back();
}
@ -1640,11 +1644,11 @@ static void GenerateDocCommentBody(
}
}
static string FirstLineOf(const string& value) {
string result = value;
static std::string FirstLineOf(const std::string& value) {
std::string result = value;
string::size_type pos = result.find_first_of('\n');
if (pos != string::npos) {
std::string::size_type pos = result.find_first_of('\n');
if (pos != std::string::npos) {
result.erase(pos);
}
@ -1801,20 +1805,18 @@ void GenerateServiceMethodDocComment(io::Printer* printer,
"return_type", EscapePhpdoc(FullClassName(method->output_type(), false)));
}
bool Generator::Generate(const FileDescriptor* file, const string& parameter,
bool Generator::Generate(const FileDescriptor* file,
const std::string& parameter,
GeneratorContext* generator_context,
string* error) const {
return Generate(file, false, false, std::set<string>(),
std::string* error) const {
return Generate(file, false, false, std::set<std::string>(),
generator_context, error);
}
bool Generator::Generate(
const FileDescriptor* file,
bool is_descriptor,
bool aggregate_metadata,
const std::set<string>& aggregate_metadata_prefixes,
GeneratorContext* generator_context,
string* error) const {
const FileDescriptor* file, bool is_descriptor, bool aggregate_metadata,
const std::set<std::string>& aggregate_metadata_prefixes,
GeneratorContext* generator_context, std::string* error) const {
if (is_descriptor && file->name() != kDescriptorFile) {
*error =
"Can only generate PHP code for google/protobuf/descriptor.proto.\n";
@ -1840,12 +1842,12 @@ bool Generator::GenerateAll(const std::vector<const FileDescriptor*>& files,
std::string* error) const {
bool is_descriptor = false;
bool aggregate_metadata = false;
std::set<string> aggregate_metadata_prefixes;
std::set<std::string> aggregate_metadata_prefixes;
for (const auto& option : Split(parameter, ",", true)) {
const std::vector<std::string> option_pair = Split(option, "=", true);
if (HasPrefixString(option_pair[0], "aggregate_metadata")) {
string options_string = option_pair[1];
std::string options_string = option_pair[1];
const std::vector<std::string> options =
Split(options_string, "#", false);
aggregate_metadata = true;

@ -47,9 +47,9 @@ class PROTOC_EXPORT Generator : public CodeGenerator {
public:
virtual bool Generate(
const FileDescriptor* file,
const string& parameter,
const std::string& parameter,
GeneratorContext* generator_context,
string* error) const override;
std::string* error) const override;
bool GenerateAll(const std::vector<const FileDescriptor*>& files,
const std::string& parameter,
@ -65,9 +65,9 @@ class PROTOC_EXPORT Generator : public CodeGenerator {
const FileDescriptor* file,
bool is_descriptor,
bool aggregate_metadata,
const std::set<string>& aggregate_metadata_prefixes,
const std::set<std::string>& aggregate_metadata_prefixes,
GeneratorContext* generator_context,
string* error) const;
std::string* error) const;
};
// To skip reserved keywords in php, some generated classname are prefixed.

@ -46,7 +46,7 @@ namespace compiler {
namespace ruby {
namespace {
string FindRubyTestDir() {
std::string FindRubyTestDir() {
return TestSourceDir() + "/google/protobuf/compiler/ruby";
}
@ -58,7 +58,7 @@ string FindRubyTestDir() {
// extensions to the point where we can do this test in a more automated way.
void RubyTest(string proto_file) {
string ruby_tests = FindRubyTestDir();
std::string ruby_tests = FindRubyTestDir();
google::protobuf::compiler::CommandLineInterface cli;
cli.SetInputsAreProtoPathRelative(true);
@ -67,7 +67,7 @@ void RubyTest(string proto_file) {
cli.RegisterGenerator("--ruby_out", &ruby_generator, "");
// Copy generated_code.proto to the temporary test directory.
string test_input;
std::string test_input;
GOOGLE_CHECK_OK(File::GetContents(
ruby_tests + proto_file + ".proto",
&test_input,
@ -78,9 +78,9 @@ void RubyTest(string proto_file) {
true));
// Invoke the proto compiler (we will be inside TestTempDir() at this point).
string ruby_out = "--ruby_out=" + TestTempDir();
string proto_path = "--proto_path=" + TestTempDir();
string proto_target = TestTempDir() + proto_file + ".proto";
std::string ruby_out = "--ruby_out=" + TestTempDir();
std::string proto_path = "--proto_path=" + TestTempDir();
std::string proto_target = TestTempDir() + proto_file + ".proto";
const char* argv[] = {
"protoc",
ruby_out.c_str(),
@ -91,12 +91,12 @@ void RubyTest(string proto_file) {
EXPECT_EQ(0, cli.Run(4, argv));
// Load the generated output and compare to the expected result.
string output;
std::string output;
GOOGLE_CHECK_OK(File::GetContentsAsText(
TestTempDir() + proto_file + "_pb.rb",
&output,
true));
string expected_output;
std::string expected_output;
GOOGLE_CHECK_OK(File::GetContentsAsText(
ruby_tests + proto_file + "_pb.rb",
&expected_output,

@ -3438,7 +3438,6 @@ class DescriptorBuilder {
void SetUInt64(int number, uint64 value, FieldDescriptor::Type type,
UnknownFieldSet* unknown_fields);
// A helper function that adds an error at the specified location of the
// option we're currently interpreting, and returns false.
bool AddOptionError(DescriptorPool::ErrorCollector::ErrorLocation location,
@ -6381,7 +6380,6 @@ DescriptorBuilder::OptionInterpreter::OptionInterpreter(
DescriptorBuilder::OptionInterpreter::~OptionInterpreter() {}
bool DescriptorBuilder::OptionInterpreter::InterpretOptions(
OptionsToInterpret* options_to_interpret) {
// Note that these may be in different pools, so we can't use the same
@ -6462,7 +6460,6 @@ bool DescriptorBuilder::OptionInterpreter::InterpretOptions(
}
}
return !failed;
}

Loading…
Cancel
Save