Merge branch 'master' into internal-merge

pull/1397/head
Josh Haberman 9 years ago
commit 4465daa57a
  1. 14
      BUILD
  2. 1
      cmake/extract_includes.bat.in
  3. 8
      objectivec/DevTools/full_mac_build.sh
  4. 7
      objectivec/GPBCodedInputStream.m
  5. 49
      objectivec/Tests/GPBCodedInputStreamTests.m
  6. 1
      src/Makefile.am
  7. 4
      src/google/protobuf/compiler/csharp/csharp_enum.cc
  8. 2
      src/google/protobuf/compiler/csharp/csharp_enum.h
  9. 11
      src/google/protobuf/compiler/csharp/csharp_enum_field.cc
  10. 8
      src/google/protobuf/compiler/csharp/csharp_enum_field.h
  11. 14
      src/google/protobuf/compiler/csharp/csharp_field_base.cc
  12. 4
      src/google/protobuf/compiler/csharp/csharp_field_base.h
  13. 26
      src/google/protobuf/compiler/csharp/csharp_generator.cc
  14. 31
      src/google/protobuf/compiler/csharp/csharp_helpers.cc
  15. 19
      src/google/protobuf/compiler/csharp/csharp_helpers.h
  16. 11
      src/google/protobuf/compiler/csharp/csharp_map_field.cc
  17. 4
      src/google/protobuf/compiler/csharp/csharp_map_field.h
  18. 21
      src/google/protobuf/compiler/csharp/csharp_message.cc
  19. 2
      src/google/protobuf/compiler/csharp/csharp_message.h
  20. 14
      src/google/protobuf/compiler/csharp/csharp_message_field.cc
  21. 8
      src/google/protobuf/compiler/csharp/csharp_message_field.h
  22. 75
      src/google/protobuf/compiler/csharp/csharp_options.h
  23. 9
      src/google/protobuf/compiler/csharp/csharp_primitive_field.cc
  24. 10
      src/google/protobuf/compiler/csharp/csharp_primitive_field.h
  25. 10
      src/google/protobuf/compiler/csharp/csharp_reflection_class.cc
  26. 6
      src/google/protobuf/compiler/csharp/csharp_reflection_class.h
  27. 4
      src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc
  28. 4
      src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h
  29. 10
      src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc
  30. 6
      src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h
  31. 4
      src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc
  32. 2
      src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h
  33. 11
      src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc
  34. 6
      src/google/protobuf/compiler/csharp/csharp_source_generator_base.h
  35. 11
      src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc
  36. 10
      src/google/protobuf/compiler/csharp/csharp_wrapper_field.h
  37. 6
      src/google/protobuf/compiler/objectivec/objectivec_enum.cc
  38. 17
      src/google/protobuf/compiler/objectivec/objectivec_field.cc
  39. 10
      src/google/protobuf/compiler/objectivec/objectivec_file.cc
  40. 16
      src/google/protobuf/compiler/objectivec/objectivec_helpers.h
  41. 3
      src/google/protobuf/compiler/objectivec/objectivec_message.cc
  42. 6
      src/google/protobuf/dynamic_message.cc

14
BUILD

@ -15,8 +15,18 @@ COPTS = [
"-Wno-error=unused-function", "-Wno-error=unused-function",
] ]
# Bazel should provide portable link_opts for pthread. config_setting(
LINK_OPTS = ["-lpthread"] name = "android",
values = {
"crosstool_top": "//external:android/crosstool",
},
)
# Android builds do not need to link in a separate pthread library.
LINK_OPTS = select({
":android": [],
"//conditions:default": ["-lpthread"],
})
load( load(
"protobuf", "protobuf",

@ -23,6 +23,7 @@ copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\command_line_
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\cpp_generator.h include\google\protobuf\compiler\cpp\cpp_generator.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\cpp\cpp_generator.h include\google\protobuf\compiler\cpp\cpp_generator.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\csharp_generator.h include\google\protobuf\compiler\csharp\csharp_generator.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\csharp_generator.h include\google\protobuf\compiler\csharp\csharp_generator.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\csharp_names.h include\google\protobuf\compiler\csharp\csharp_names.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\csharp_names.h include\google\protobuf\compiler\csharp\csharp_names.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\csharp\csharp_options.h include\google\protobuf\compiler\csharp\csharp_options.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\importer.h include\google\protobuf\compiler\importer.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\importer.h include\google\protobuf\compiler\importer.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\java_generator.h include\google\protobuf\compiler\java\java_generator.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\java_generator.h include\google\protobuf\compiler\java\java_generator.h
copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\java_names.h include\google\protobuf\compiler\java\java_names.h copy ${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\java\java_names.h include\google\protobuf\compiler\java\java_names.h

@ -242,6 +242,14 @@ if [[ "${DO_XCODE_IOS_TESTS}" == "yes" ]] ; then
-destination "platform=iOS Simulator,name=iPad Air,OS=9.0" # 64bit -destination "platform=iOS Simulator,name=iPad Air,OS=9.0" # 64bit
) )
;; ;;
7.3* )
XCODEBUILD_TEST_BASE_IOS+=(
-destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit
-destination "platform=iOS Simulator,name=iPhone 6,OS=9.3" # 64bit
-destination "platform=iOS Simulator,name=iPad 2,OS=8.1" # 32bit
-destination "platform=iOS Simulator,name=iPad Air,OS=9.3" # 64bit
)
;;
7.* ) 7.* )
XCODEBUILD_TEST_BASE_IOS+=( XCODEBUILD_TEST_BASE_IOS+=(
-destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit -destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit

@ -219,15 +219,16 @@ NSString *GPBCodedInputStreamReadRetainedString(
result = [[NSString alloc] initWithBytes:&state->bytes[state->bufferPos] result = [[NSString alloc] initWithBytes:&state->bytes[state->bufferPos]
length:size length:size
encoding:NSUTF8StringEncoding]; encoding:NSUTF8StringEncoding];
state->bufferPos += size;
if (!result) { if (!result) {
result = @"";
#ifdef DEBUG #ifdef DEBUG
// https://developers.google.com/protocol-buffers/docs/proto#scalar // https://developers.google.com/protocol-buffers/docs/proto#scalar
NSLog(@"UTF8 failure, is some field type 'string' when it should be " NSLog(@"UTF-8 failure, is some field type 'string' when it should be "
@"'bytes'?"); @"'bytes'?");
#endif #endif
[NSException raise:NSParseErrorException
format:@"Invalid UTF-8 for a 'string'"];
} }
state->bufferPos += size;
} }
return result; return result;
} }

@ -283,16 +283,53 @@
[output writeRawData:[NSData dataWithBytes:bytes length:sizeof(bytes)]]; [output writeRawData:[NSData dataWithBytes:bytes length:sizeof(bytes)]];
[output flush]; [output flush];
NSData* data = NSData *data =
[rawOutput propertyForKey:NSStreamDataWrittenToMemoryStreamKey]; [rawOutput propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data]; GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data];
NSError *error = nil;
TestAllTypes* message = [TestAllTypes parseFromCodedInputStream:input TestAllTypes* message = [TestAllTypes parseFromCodedInputStream:input
extensionRegistry:nil extensionRegistry:nil
error:NULL]; error:&error];
XCTAssertNotNil(message); XCTAssertNotNil(error);
// Make sure we can read string properties twice without crashing. XCTAssertNil(message);
XCTAssertEqual([message.defaultString length], (NSUInteger)0); }
XCTAssertEqualObjects(@"", message.defaultString);
- (void)testBOMWithinStrings {
// We've seen servers that end up with BOMs within strings (not always at the
// start, and sometimes in multiple places), make sure they always parse
// correctly. (Again, this is inpart incase a custom string class is ever
// used again.)
const char* strs[] = {
"\xEF\xBB\xBF String with BOM",
"String with \xEF\xBB\xBF in middle",
"String with end bom \xEF\xBB\xBF",
"\xEF\xBB\xBF\xe2\x99\xa1", // BOM White Heart
"\xEF\xBB\xBF\xEF\xBB\xBF String with Two BOM",
};
for (size_t i = 0; i < GPBARRAYSIZE(strs); ++i) {
NSOutputStream* rawOutput = [NSOutputStream outputStreamToMemory];
GPBCodedOutputStream* output =
[GPBCodedOutputStream streamWithOutputStream:rawOutput];
int32_t tag = GPBWireFormatMakeTag(TestAllTypes_FieldNumber_DefaultString,
GPBWireFormatLengthDelimited);
[output writeRawVarint32:tag];
size_t length = strlen(strs[i]);
[output writeRawVarint32:(int32_t)length];
[output writeRawData:[NSData dataWithBytes:strs[i] length:length]];
[output flush];
NSData* data =
[rawOutput propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data];
TestAllTypes* message = [TestAllTypes parseFromCodedInputStream:input
extensionRegistry:nil
error:NULL];
XCTAssertNotNil(message, @"Loop %zd", i);
// Ensure the string is there. NSString can consume the BOM in some
// cases, so don't actually check the string for exact equality.
XCTAssertTrue(message.defaultString.length > 0, @"Loop %zd", i);
}
} }
@end @end

@ -455,6 +455,7 @@ libprotoc_la_SOURCES = \
google/protobuf/compiler/csharp/csharp_message.h \ google/protobuf/compiler/csharp/csharp_message.h \
google/protobuf/compiler/csharp/csharp_message_field.cc \ google/protobuf/compiler/csharp/csharp_message_field.cc \
google/protobuf/compiler/csharp/csharp_message_field.h \ google/protobuf/compiler/csharp/csharp_message_field.h \
google/protobuf/compiler/csharp/csharp_options.h \
google/protobuf/compiler/csharp/csharp_primitive_field.cc \ google/protobuf/compiler/csharp/csharp_primitive_field.cc \
google/protobuf/compiler/csharp/csharp_primitive_field.h \ google/protobuf/compiler/csharp/csharp_primitive_field.h \
google/protobuf/compiler/csharp/csharp_reflection_class.cc \ google/protobuf/compiler/csharp/csharp_reflection_class.cc \

@ -49,8 +49,8 @@ namespace protobuf {
namespace compiler { namespace compiler {
namespace csharp { namespace csharp {
EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor) : EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor, const Options* options) :
SourceGeneratorBase(descriptor->file()), SourceGeneratorBase(descriptor->file(), options),
descriptor_(descriptor) { descriptor_(descriptor) {
} }

@ -43,7 +43,7 @@ namespace csharp {
class EnumGenerator : public SourceGeneratorBase { class EnumGenerator : public SourceGeneratorBase {
public: public:
EnumGenerator(const EnumDescriptor* descriptor); EnumGenerator(const EnumDescriptor* descriptor, const Options* options);
~EnumGenerator(); ~EnumGenerator();
void Generate(io::Printer* printer); void Generate(io::Printer* printer);

@ -38,6 +38,7 @@
#include <google/protobuf/io/zero_copy_stream.h> #include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h> #include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/compiler/csharp/csharp_options.h>
#include <google/protobuf/compiler/csharp/csharp_enum_field.h> #include <google/protobuf/compiler/csharp/csharp_enum_field.h>
namespace google { namespace google {
@ -46,8 +47,8 @@ namespace compiler {
namespace csharp { namespace csharp {
EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor, EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor,
int fieldOrdinal) int fieldOrdinal, const Options *options)
: PrimitiveFieldGenerator(descriptor, fieldOrdinal) { : PrimitiveFieldGenerator(descriptor, fieldOrdinal, options) {
} }
EnumFieldGenerator::~EnumFieldGenerator() { EnumFieldGenerator::~EnumFieldGenerator() {
@ -80,9 +81,9 @@ void EnumFieldGenerator::GenerateCodecCode(io::Printer* printer) {
"pb::FieldCodec.ForEnum($tag$, x => (int) x, x => ($type_name$) x)"); "pb::FieldCodec.ForEnum($tag$, x => (int) x, x => ($type_name$) x)");
} }
EnumOneofFieldGenerator::EnumOneofFieldGenerator(const FieldDescriptor* descriptor, EnumOneofFieldGenerator::EnumOneofFieldGenerator(
int fieldOrdinal) const FieldDescriptor* descriptor, int fieldOrdinal, const Options *options)
: PrimitiveOneofFieldGenerator(descriptor, fieldOrdinal) { : PrimitiveOneofFieldGenerator(descriptor, fieldOrdinal, options) {
} }
EnumOneofFieldGenerator::~EnumOneofFieldGenerator() { EnumOneofFieldGenerator::~EnumOneofFieldGenerator() {

@ -43,7 +43,9 @@ namespace csharp {
class EnumFieldGenerator : public PrimitiveFieldGenerator { class EnumFieldGenerator : public PrimitiveFieldGenerator {
public: public:
EnumFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); EnumFieldGenerator(const FieldDescriptor* descriptor,
int fieldOrdinal,
const Options *options);
~EnumFieldGenerator(); ~EnumFieldGenerator();
virtual void GenerateCodecCode(io::Printer* printer); virtual void GenerateCodecCode(io::Printer* printer);
@ -57,7 +59,9 @@ class EnumFieldGenerator : public PrimitiveFieldGenerator {
class EnumOneofFieldGenerator : public PrimitiveOneofFieldGenerator { class EnumOneofFieldGenerator : public PrimitiveOneofFieldGenerator {
public: public:
EnumOneofFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); EnumOneofFieldGenerator(const FieldDescriptor* descriptor,
int fieldOrdinal,
const Options *options);
~EnumOneofFieldGenerator(); ~EnumOneofFieldGenerator();
virtual void GenerateParsingCode(io::Printer* printer); virtual void GenerateParsingCode(io::Printer* printer);

@ -94,14 +94,15 @@ void FieldGeneratorBase::SetCommonFieldVariables(
void FieldGeneratorBase::SetCommonOneofFieldVariables( void FieldGeneratorBase::SetCommonOneofFieldVariables(
map<string, string>* variables) { map<string, string>* variables) {
(*variables)["oneof_name"] = oneof_name(); (*variables)["oneof_name"] = oneof_name();
(*variables)["has_property_check"] = oneof_name() + "Case_ == " + oneof_property_name() + (*variables)["has_property_check"] =
oneof_name() + "Case_ == " + oneof_property_name() +
"OneofCase." + property_name(); "OneofCase." + property_name();
(*variables)["oneof_property_name"] = oneof_property_name(); (*variables)["oneof_property_name"] = oneof_property_name();
} }
FieldGeneratorBase::FieldGeneratorBase(const FieldDescriptor* descriptor, FieldGeneratorBase::FieldGeneratorBase(const FieldDescriptor* descriptor,
int fieldOrdinal) int fieldOrdinal, const Options* options)
: SourceGeneratorBase(descriptor->file()), : SourceGeneratorBase(descriptor->file(), options),
descriptor_(descriptor), descriptor_(descriptor),
fieldOrdinal_(fieldOrdinal) { fieldOrdinal_(fieldOrdinal) {
SetCommonFieldVariables(&variables_); SetCommonFieldVariables(&variables_);
@ -158,10 +159,11 @@ std::string FieldGeneratorBase::type_name(const FieldDescriptor* descriptor) {
case FieldDescriptor::TYPE_MESSAGE: case FieldDescriptor::TYPE_MESSAGE:
case FieldDescriptor::TYPE_GROUP: case FieldDescriptor::TYPE_GROUP:
if (IsWrapperType(descriptor)) { if (IsWrapperType(descriptor)) {
const FieldDescriptor* wrapped_field = descriptor->message_type()->field(0); const FieldDescriptor* wrapped_field =
descriptor->message_type()->field(0);
string wrapped_field_type_name = type_name(wrapped_field); string wrapped_field_type_name = type_name(wrapped_field);
// String and ByteString go to the same type; other wrapped types go to the // String and ByteString go to the same type; other wrapped types
// nullable equivalent. // go to the nullable equivalent.
if (wrapped_field->type() == FieldDescriptor::TYPE_STRING || if (wrapped_field->type() == FieldDescriptor::TYPE_STRING ||
wrapped_field->type() == FieldDescriptor::TYPE_BYTES) { wrapped_field->type() == FieldDescriptor::TYPE_BYTES) {
return wrapped_field_type_name; return wrapped_field_type_name;

@ -44,7 +44,9 @@ namespace csharp {
class FieldGeneratorBase : public SourceGeneratorBase { class FieldGeneratorBase : public SourceGeneratorBase {
public: public:
FieldGeneratorBase(const FieldDescriptor* descriptor, int fieldOrdinal); FieldGeneratorBase(const FieldDescriptor* descriptor,
int fieldOrdinal,
const Options* options);
~FieldGeneratorBase(); ~FieldGeneratorBase();
virtual void GenerateCloningCode(io::Printer* printer) = 0; virtual void GenerateCloningCode(io::Printer* printer) = 0;

@ -41,6 +41,7 @@
#include <google/protobuf/compiler/csharp/csharp_generator.h> #include <google/protobuf/compiler/csharp/csharp_generator.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h> #include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/compiler/csharp/csharp_names.h> #include <google/protobuf/compiler/csharp/csharp_names.h>
#include <google/protobuf/compiler/csharp/csharp_options.h>
#include <google/protobuf/compiler/csharp/csharp_reflection_class.h> #include <google/protobuf/compiler/csharp/csharp_reflection_class.h>
using google::protobuf::internal::scoped_ptr; using google::protobuf::internal::scoped_ptr;
@ -51,8 +52,9 @@ namespace compiler {
namespace csharp { namespace csharp {
void GenerateFile(const google::protobuf::FileDescriptor* file, void GenerateFile(const google::protobuf::FileDescriptor* file,
io::Printer* printer) { io::Printer* printer,
ReflectionClassGenerator reflectionClassGenerator(file); const Options* options) {
ReflectionClassGenerator reflectionClassGenerator(file, options);
reflectionClassGenerator.Generate(printer); reflectionClassGenerator.Generate(printer);
} }
@ -71,15 +73,14 @@ bool Generator::Generate(
return false; return false;
} }
std::string file_extension = ".cs"; struct Options cli_options;
std::string base_namespace = "";
bool generate_directories = false;
for (int i = 0; i < options.size(); i++) { for (int i = 0; i < options.size(); i++) {
if (options[i].first == "file_extension") { if (options[i].first == "file_extension") {
file_extension = options[i].second; cli_options.file_extension = options[i].second;
} else if (options[i].first == "base_namespace") { } else if (options[i].first == "base_namespace") {
base_namespace = options[i].second; cli_options.base_namespace = options[i].second;
generate_directories = true; cli_options.base_namespace_specified = true;
} else { } else {
*error = "Unknown generator option: " + options[i].first; *error = "Unknown generator option: " + options[i].first;
return false; return false;
@ -87,7 +88,12 @@ bool Generator::Generate(
} }
string filename_error = ""; string filename_error = "";
std::string filename = GetOutputFile(file, file_extension, generate_directories, base_namespace, &filename_error); std::string filename = GetOutputFile(file,
cli_options.file_extension,
cli_options.base_namespace_specified,
cli_options.base_namespace,
&filename_error);
if (filename.empty()) { if (filename.empty()) {
*error = filename_error; *error = filename_error;
return false; return false;
@ -96,7 +102,7 @@ bool Generator::Generate(
generator_context->Open(filename)); generator_context->Open(filename));
io::Printer printer(output.get(), '$'); io::Printer printer(output.get(), '$');
GenerateFile(file, &printer); GenerateFile(file, &printer, &cli_options);
return true; return true;
} }

@ -48,6 +48,7 @@
#include <google/protobuf/compiler/csharp/csharp_enum_field.h> #include <google/protobuf/compiler/csharp/csharp_enum_field.h>
#include <google/protobuf/compiler/csharp/csharp_map_field.h> #include <google/protobuf/compiler/csharp/csharp_map_field.h>
#include <google/protobuf/compiler/csharp/csharp_message_field.h> #include <google/protobuf/compiler/csharp/csharp_message_field.h>
#include <google/protobuf/compiler/csharp/csharp_options.h>
#include <google/protobuf/compiler/csharp/csharp_primitive_field.h> #include <google/protobuf/compiler/csharp/csharp_primitive_field.h>
#include <google/protobuf/compiler/csharp/csharp_repeated_enum_field.h> #include <google/protobuf/compiler/csharp/csharp_repeated_enum_field.h>
#include <google/protobuf/compiler/csharp/csharp_repeated_message_field.h> #include <google/protobuf/compiler/csharp/csharp_repeated_message_field.h>
@ -127,7 +128,8 @@ std::string GetFileNameBase(const FileDescriptor* descriptor) {
} }
std::string GetReflectionClassUnqualifiedName(const FileDescriptor* descriptor) { std::string GetReflectionClassUnqualifiedName(const FileDescriptor* descriptor) {
// TODO: Detect collisions with existing messages, and append an underscore if necessary. // TODO: Detect collisions with existing messages,
// and append an underscore if necessary.
return GetFileNameBase(descriptor) + "Reflection"; return GetFileNameBase(descriptor) + "Reflection";
} }
@ -351,49 +353,50 @@ std::string FileDescriptorToBase64(const FileDescriptor* descriptor) {
} }
FieldGeneratorBase* CreateFieldGenerator(const FieldDescriptor* descriptor, FieldGeneratorBase* CreateFieldGenerator(const FieldDescriptor* descriptor,
int fieldOrdinal) { int fieldOrdinal,
const Options* options) {
switch (descriptor->type()) { switch (descriptor->type()) {
case FieldDescriptor::TYPE_GROUP: case FieldDescriptor::TYPE_GROUP:
case FieldDescriptor::TYPE_MESSAGE: case FieldDescriptor::TYPE_MESSAGE:
if (descriptor->is_repeated()) { if (descriptor->is_repeated()) {
if (descriptor->is_map()) { if (descriptor->is_map()) {
return new MapFieldGenerator(descriptor, fieldOrdinal); return new MapFieldGenerator(descriptor, fieldOrdinal, options);
} else { } else {
return new RepeatedMessageFieldGenerator(descriptor, fieldOrdinal); return new RepeatedMessageFieldGenerator(descriptor, fieldOrdinal, options);
} }
} else { } else {
if (IsWrapperType(descriptor)) { if (IsWrapperType(descriptor)) {
if (descriptor->containing_oneof()) { if (descriptor->containing_oneof()) {
return new WrapperOneofFieldGenerator(descriptor, fieldOrdinal); return new WrapperOneofFieldGenerator(descriptor, fieldOrdinal, options);
} else { } else {
return new WrapperFieldGenerator(descriptor, fieldOrdinal); return new WrapperFieldGenerator(descriptor, fieldOrdinal, options);
} }
} else { } else {
if (descriptor->containing_oneof()) { if (descriptor->containing_oneof()) {
return new MessageOneofFieldGenerator(descriptor, fieldOrdinal); return new MessageOneofFieldGenerator(descriptor, fieldOrdinal, options);
} else { } else {
return new MessageFieldGenerator(descriptor, fieldOrdinal); return new MessageFieldGenerator(descriptor, fieldOrdinal, options);
} }
} }
} }
case FieldDescriptor::TYPE_ENUM: case FieldDescriptor::TYPE_ENUM:
if (descriptor->is_repeated()) { if (descriptor->is_repeated()) {
return new RepeatedEnumFieldGenerator(descriptor, fieldOrdinal); return new RepeatedEnumFieldGenerator(descriptor, fieldOrdinal, options);
} else { } else {
if (descriptor->containing_oneof()) { if (descriptor->containing_oneof()) {
return new EnumOneofFieldGenerator(descriptor, fieldOrdinal); return new EnumOneofFieldGenerator(descriptor, fieldOrdinal, options);
} else { } else {
return new EnumFieldGenerator(descriptor, fieldOrdinal); return new EnumFieldGenerator(descriptor, fieldOrdinal, options);
} }
} }
default: default:
if (descriptor->is_repeated()) { if (descriptor->is_repeated()) {
return new RepeatedPrimitiveFieldGenerator(descriptor, fieldOrdinal); return new RepeatedPrimitiveFieldGenerator(descriptor, fieldOrdinal, options);
} else { } else {
if (descriptor->containing_oneof()) { if (descriptor->containing_oneof()) {
return new PrimitiveOneofFieldGenerator(descriptor, fieldOrdinal); return new PrimitiveOneofFieldGenerator(descriptor, fieldOrdinal, options);
} else { } else {
return new PrimitiveFieldGenerator(descriptor, fieldOrdinal); return new PrimitiveFieldGenerator(descriptor, fieldOrdinal, options);
} }
} }
} }

@ -46,6 +46,7 @@ namespace protobuf {
namespace compiler { namespace compiler {
namespace csharp { namespace csharp {
struct Options;
class FieldGeneratorBase; class FieldGeneratorBase;
// TODO: start using this enum. // TODO: start using this enum.
@ -82,7 +83,9 @@ std::string GetPropertyName(const FieldDescriptor* descriptor);
int GetFixedSize(FieldDescriptor::Type type); int GetFixedSize(FieldDescriptor::Type type);
std::string UnderscoresToCamelCase(const std::string& input, bool cap_next_letter, bool preserve_period); std::string UnderscoresToCamelCase(const std::string& input,
bool cap_next_letter,
bool preserve_period);
inline std::string UnderscoresToCamelCase(const std::string& input, bool cap_next_letter) { inline std::string UnderscoresToCamelCase(const std::string& input, bool cap_next_letter) {
return UnderscoresToCamelCase(input, cap_next_letter, false); return UnderscoresToCamelCase(input, cap_next_letter, false);
@ -95,17 +98,19 @@ std::string StringToBase64(const std::string& input);
std::string FileDescriptorToBase64(const FileDescriptor* descriptor); std::string FileDescriptorToBase64(const FileDescriptor* descriptor);
FieldGeneratorBase* CreateFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); FieldGeneratorBase* CreateFieldGenerator(const FieldDescriptor* descriptor,
int fieldOrdinal,
const Options* options);
// Determines whether the given message is a map entry message, i.e. one implicitly created // Determines whether the given message is a map entry message,
// by protoc due to a map<key, value> field. // i.e. one implicitly created by protoc due to a map<key, value> field.
inline bool IsMapEntryMessage(const Descriptor* descriptor) { inline bool IsMapEntryMessage(const Descriptor* descriptor) {
return descriptor->options().map_entry(); return descriptor->options().map_entry();
} }
// Determines whether we're generating code for the proto representation of descriptors etc, // Determines whether we're generating code for the proto representation of
// for use in the runtime. This is the only type which is allowed to use proto2 syntax, // descriptors etc, for use in the runtime. This is the only type which is
// and it generates internal classes. // allowed to use proto2 syntax, and it generates internal classes.
inline bool IsDescriptorProto(const FileDescriptor* descriptor) { inline bool IsDescriptorProto(const FileDescriptor* descriptor) {
return descriptor->name() == "google/protobuf/descriptor.proto"; return descriptor->name() == "google/protobuf/descriptor.proto";
} }

@ -48,8 +48,9 @@ namespace compiler {
namespace csharp { namespace csharp {
MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor, MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor,
int fieldOrdinal) int fieldOrdinal,
: FieldGeneratorBase(descriptor, fieldOrdinal) { const Options* options)
: FieldGeneratorBase(descriptor, fieldOrdinal, options) {
} }
MapFieldGenerator::~MapFieldGenerator() { MapFieldGenerator::~MapFieldGenerator() {
@ -62,8 +63,10 @@ void MapFieldGenerator::GenerateMembers(io::Printer* printer) {
descriptor_->message_type()->FindFieldByName("value"); descriptor_->message_type()->FindFieldByName("value");
variables_["key_type_name"] = type_name(key_descriptor); variables_["key_type_name"] = type_name(key_descriptor);
variables_["value_type_name"] = type_name(value_descriptor); variables_["value_type_name"] = type_name(value_descriptor);
scoped_ptr<FieldGeneratorBase> key_generator(CreateFieldGenerator(key_descriptor, 1)); scoped_ptr<FieldGeneratorBase> key_generator(
scoped_ptr<FieldGeneratorBase> value_generator(CreateFieldGenerator(value_descriptor, 2)); CreateFieldGenerator(key_descriptor, 1, this->options()));
scoped_ptr<FieldGeneratorBase> value_generator(
CreateFieldGenerator(value_descriptor, 2, this->options()));
printer->Print( printer->Print(
variables_, variables_,

@ -43,7 +43,9 @@ namespace csharp {
class MapFieldGenerator : public FieldGeneratorBase { class MapFieldGenerator : public FieldGeneratorBase {
public: public:
MapFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); MapFieldGenerator(const FieldDescriptor* descriptor,
int fieldOrdinal,
const Options* options);
~MapFieldGenerator(); ~MapFieldGenerator();
virtual void GenerateCloningCode(io::Printer* printer); virtual void GenerateCloningCode(io::Printer* printer);

@ -60,8 +60,9 @@ bool CompareFieldNumbers(const FieldDescriptor* d1, const FieldDescriptor* d2) {
return d1->number() < d2->number(); return d1->number() < d2->number();
} }
MessageGenerator::MessageGenerator(const Descriptor* descriptor) MessageGenerator::MessageGenerator(const Descriptor* descriptor,
: SourceGeneratorBase(descriptor->file()), const Options* options)
: SourceGeneratorBase(descriptor->file(), options),
descriptor_(descriptor) { descriptor_(descriptor) {
// sorted field names // sorted field names
@ -185,7 +186,8 @@ void MessageGenerator::Generate(io::Printer* printer) {
} }
printer->Outdent(); printer->Outdent();
printer->Print("}\n"); printer->Print("}\n");
// TODO: Should we put the oneof .proto comments here? It's unclear exactly where they should go. // TODO: Should we put the oneof .proto comments here?
// It's unclear exactly where they should go.
printer->Print( printer->Print(
vars, vars,
"private $property_name$OneofCase $name$Case_ = $property_name$OneofCase.None;\n" "private $property_name$OneofCase $name$Case_ = $property_name$OneofCase.None;\n"
@ -214,13 +216,14 @@ void MessageGenerator::Generate(io::Printer* printer) {
printer->Print("public static partial class Types {\n"); printer->Print("public static partial class Types {\n");
printer->Indent(); printer->Indent();
for (int i = 0; i < descriptor_->enum_type_count(); i++) { for (int i = 0; i < descriptor_->enum_type_count(); i++) {
EnumGenerator enumGenerator(descriptor_->enum_type(i)); EnumGenerator enumGenerator(descriptor_->enum_type(i), this->options());
enumGenerator.Generate(printer); enumGenerator.Generate(printer);
} }
for (int i = 0; i < descriptor_->nested_type_count(); i++) { for (int i = 0; i < descriptor_->nested_type_count(); i++) {
// Don't generate nested types for maps... // Don't generate nested types for maps...
if (!IsMapEntryMessage(descriptor_->nested_type(i))) { if (!IsMapEntryMessage(descriptor_->nested_type(i))) {
MessageGenerator messageGenerator(descriptor_->nested_type(i)); MessageGenerator messageGenerator(
descriptor_->nested_type(i), this->options());
messageGenerator.Generate(printer); messageGenerator.Generate(printer);
} }
} }
@ -268,7 +271,8 @@ void MessageGenerator::GenerateCloningCode(io::Printer* printer) {
// Clone just the right field for each oneof // Clone just the right field for each oneof
for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) { for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
vars["name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false); vars["name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false);
vars["property_name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true); vars["property_name"] = UnderscoresToCamelCase(
descriptor_->oneof_decl(i)->name(), true);
printer->Print(vars, "switch (other.$property_name$Case) {\n"); printer->Print(vars, "switch (other.$property_name$Case) {\n");
printer->Indent(); printer->Indent();
for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
@ -449,7 +453,8 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) {
uint32 tag = internal::WireFormatLite::MakeTag(field->number(), wt); uint32 tag = internal::WireFormatLite::MakeTag(field->number(), wt);
// Handle both packed and unpacked repeated fields with the same Read*Array call; // Handle both packed and unpacked repeated fields with the same Read*Array call;
// the two generated cases are the packed and unpacked tags. // the two generated cases are the packed and unpacked tags.
// TODO(jonskeet): Check that is_packable is equivalent to is_repeated && wt in { VARINT, FIXED32, FIXED64 }. // TODO(jonskeet): Check that is_packable is equivalent to
// is_repeated && wt in { VARINT, FIXED32, FIXED64 }.
// It looks like it is... // It looks like it is...
if (field->is_packable()) { if (field->is_packable()) {
printer->Print( printer->Print(
@ -490,7 +495,7 @@ int MessageGenerator::GetFieldOrdinal(const FieldDescriptor* descriptor) {
FieldGeneratorBase* MessageGenerator::CreateFieldGeneratorInternal( FieldGeneratorBase* MessageGenerator::CreateFieldGeneratorInternal(
const FieldDescriptor* descriptor) { const FieldDescriptor* descriptor) {
return CreateFieldGenerator(descriptor, GetFieldOrdinal(descriptor)); return CreateFieldGenerator(descriptor, GetFieldOrdinal(descriptor), this->options());
} }
} // namespace csharp } // namespace csharp

@ -47,7 +47,7 @@ class FieldGeneratorBase;
class MessageGenerator : public SourceGeneratorBase { class MessageGenerator : public SourceGeneratorBase {
public: public:
MessageGenerator(const Descriptor* descriptor); MessageGenerator(const Descriptor* descriptor, const Options* options);
~MessageGenerator(); ~MessageGenerator();
void GenerateCloningCode(io::Printer* printer); void GenerateCloningCode(io::Printer* printer);

@ -41,6 +41,7 @@
#include <google/protobuf/compiler/csharp/csharp_doc_comment.h> #include <google/protobuf/compiler/csharp/csharp_doc_comment.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h> #include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/compiler/csharp/csharp_message_field.h> #include <google/protobuf/compiler/csharp/csharp_message_field.h>
#include <google/protobuf/compiler/csharp/csharp_options.h>
namespace google { namespace google {
namespace protobuf { namespace protobuf {
@ -48,8 +49,9 @@ namespace compiler {
namespace csharp { namespace csharp {
MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor, MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor,
int fieldOrdinal) int fieldOrdinal,
: FieldGeneratorBase(descriptor, fieldOrdinal) { const Options *options)
: FieldGeneratorBase(descriptor, fieldOrdinal, options) {
variables_["has_property_check"] = name() + "_ != null"; variables_["has_property_check"] = name() + "_ != null";
variables_["has_not_property_check"] = name() + "_ == null"; variables_["has_not_property_check"] = name() + "_ == null";
} }
@ -143,9 +145,11 @@ void MessageFieldGenerator::GenerateCodecCode(io::Printer* printer) {
"pb::FieldCodec.ForMessage($tag$, $type_name$.Parser)"); "pb::FieldCodec.ForMessage($tag$, $type_name$.Parser)");
} }
MessageOneofFieldGenerator::MessageOneofFieldGenerator(const FieldDescriptor* descriptor, MessageOneofFieldGenerator::MessageOneofFieldGenerator(
int fieldOrdinal) const FieldDescriptor* descriptor,
: MessageFieldGenerator(descriptor, fieldOrdinal) { int fieldOrdinal,
const Options *options)
: MessageFieldGenerator(descriptor, fieldOrdinal, options) {
SetCommonOneofFieldVariables(&variables_); SetCommonOneofFieldVariables(&variables_);
} }

@ -43,7 +43,9 @@ namespace csharp {
class MessageFieldGenerator : public FieldGeneratorBase { class MessageFieldGenerator : public FieldGeneratorBase {
public: public:
MessageFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); MessageFieldGenerator(const FieldDescriptor* descriptor,
int fieldOrdinal,
const Options *options);
~MessageFieldGenerator(); ~MessageFieldGenerator();
virtual void GenerateCodecCode(io::Printer* printer); virtual void GenerateCodecCode(io::Printer* printer);
@ -65,7 +67,9 @@ class MessageFieldGenerator : public FieldGeneratorBase {
class MessageOneofFieldGenerator : public MessageFieldGenerator { class MessageOneofFieldGenerator : public MessageFieldGenerator {
public: public:
MessageOneofFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); MessageOneofFieldGenerator(const FieldDescriptor* descriptor,
int fieldOrdinal,
const Options *options);
~MessageOneofFieldGenerator(); ~MessageOneofFieldGenerator();
virtual void GenerateCloningCode(io::Printer* printer); virtual void GenerateCloningCode(io::Printer* printer);

@ -0,0 +1,75 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_OPTIONS_H__
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_OPTIONS_H__
#include <string>
#include <google/protobuf/stubs/common.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
// Generator options (used by csharp_generator.cc):
struct Options {
Options() :
file_extension(".cs"),
base_namespace(""),
base_namespace_specified(false) {
}
// Extension of the generated file. Defaults to ".cs"
string file_extension;
// Base namespace to use to create directory hierarchy. Defaults to "".
// This option allows the simple creation of a conventional C# file layout,
// where directories are created relative to a project-specific base
// namespace. For example, in a project with a base namespace of PetShop, a
// proto of user.proto with a C# namespace of PetShop.Model.Shared would
// generate Model/Shared/User.cs underneath the specified --csharp_out
// directory.
//
// If no base namespace is specified, all files are generated in the
// --csharp_out directory, with no subdirectories created automatically.
string base_namespace;
// Whether the base namespace has been explicitly specified by the user.
// This is required as the base namespace can be explicitly set to the empty
// string, meaning "create a full directory hierarchy, starting from the first
// segment of the namespace."
bool base_namespace_specified;
};
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_OPTIONS_H__

@ -40,6 +40,7 @@
#include <google/protobuf/compiler/csharp/csharp_doc_comment.h> #include <google/protobuf/compiler/csharp/csharp_doc_comment.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h> #include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/compiler/csharp/csharp_options.h>
#include <google/protobuf/compiler/csharp/csharp_primitive_field.h> #include <google/protobuf/compiler/csharp/csharp_primitive_field.h>
namespace google { namespace google {
@ -48,8 +49,8 @@ namespace compiler {
namespace csharp { namespace csharp {
PrimitiveFieldGenerator::PrimitiveFieldGenerator( PrimitiveFieldGenerator::PrimitiveFieldGenerator(
const FieldDescriptor* descriptor, int fieldOrdinal) const FieldDescriptor* descriptor, int fieldOrdinal, const Options *options)
: FieldGeneratorBase(descriptor, fieldOrdinal) { : FieldGeneratorBase(descriptor, fieldOrdinal, options) {
// TODO(jonskeet): Make this cleaner... // TODO(jonskeet): Make this cleaner...
is_value_type = descriptor->type() != FieldDescriptor::TYPE_STRING is_value_type = descriptor->type() != FieldDescriptor::TYPE_STRING
&& descriptor->type() != FieldDescriptor::TYPE_BYTES; && descriptor->type() != FieldDescriptor::TYPE_BYTES;
@ -163,8 +164,8 @@ void PrimitiveFieldGenerator::GenerateCodecCode(io::Printer* printer) {
} }
PrimitiveOneofFieldGenerator::PrimitiveOneofFieldGenerator( PrimitiveOneofFieldGenerator::PrimitiveOneofFieldGenerator(
const FieldDescriptor* descriptor, int fieldOrdinal) const FieldDescriptor* descriptor, int fieldOrdinal, const Options *options)
: PrimitiveFieldGenerator(descriptor, fieldOrdinal) { : PrimitiveFieldGenerator(descriptor, fieldOrdinal, options) {
SetCommonOneofFieldVariables(&variables_); SetCommonOneofFieldVariables(&variables_);
} }

@ -41,9 +41,13 @@ namespace protobuf {
namespace compiler { namespace compiler {
namespace csharp { namespace csharp {
struct Options;
class PrimitiveFieldGenerator : public FieldGeneratorBase { class PrimitiveFieldGenerator : public FieldGeneratorBase {
public: public:
PrimitiveFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); PrimitiveFieldGenerator(const FieldDescriptor* descriptor,
int fieldOrdinal,
const Options *options);
~PrimitiveFieldGenerator(); ~PrimitiveFieldGenerator();
virtual void GenerateCodecCode(io::Printer* printer); virtual void GenerateCodecCode(io::Printer* printer);
@ -67,7 +71,9 @@ class PrimitiveFieldGenerator : public FieldGeneratorBase {
class PrimitiveOneofFieldGenerator : public PrimitiveFieldGenerator { class PrimitiveOneofFieldGenerator : public PrimitiveFieldGenerator {
public: public:
PrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); PrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor,
int fieldOrdinal,
const Options *options);
~PrimitiveOneofFieldGenerator(); ~PrimitiveOneofFieldGenerator();
virtual void GenerateCloningCode(io::Printer* printer); virtual void GenerateCloningCode(io::Printer* printer);

@ -43,6 +43,7 @@
#include <google/protobuf/compiler/csharp/csharp_helpers.h> #include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/compiler/csharp/csharp_message.h> #include <google/protobuf/compiler/csharp/csharp_message.h>
#include <google/protobuf/compiler/csharp/csharp_names.h> #include <google/protobuf/compiler/csharp/csharp_names.h>
#include <google/protobuf/compiler/csharp/csharp_options.h>
#include <google/protobuf/compiler/csharp/csharp_reflection_class.h> #include <google/protobuf/compiler/csharp/csharp_reflection_class.h>
namespace google { namespace google {
@ -50,8 +51,9 @@ namespace protobuf {
namespace compiler { namespace compiler {
namespace csharp { namespace csharp {
ReflectionClassGenerator::ReflectionClassGenerator(const FileDescriptor* file) ReflectionClassGenerator::ReflectionClassGenerator(const FileDescriptor* file,
: SourceGeneratorBase(file), const Options* options)
: SourceGeneratorBase(file, options),
file_(file) { file_(file) {
namespace_ = GetFileNamespace(file); namespace_ = GetFileNamespace(file);
reflectionClassname_ = GetReflectionClassUnqualifiedName(file); reflectionClassname_ = GetReflectionClassUnqualifiedName(file);
@ -72,7 +74,7 @@ void ReflectionClassGenerator::Generate(io::Printer* printer) {
if (file_->enum_type_count() > 0) { if (file_->enum_type_count() > 0) {
printer->Print("#region Enums\n"); printer->Print("#region Enums\n");
for (int i = 0; i < file_->enum_type_count(); i++) { for (int i = 0; i < file_->enum_type_count(); i++) {
EnumGenerator enumGenerator(file_->enum_type(i)); EnumGenerator enumGenerator(file_->enum_type(i), this->options());
enumGenerator.Generate(printer); enumGenerator.Generate(printer);
} }
printer->Print("#endregion\n"); printer->Print("#endregion\n");
@ -83,7 +85,7 @@ void ReflectionClassGenerator::Generate(io::Printer* printer) {
if (file_->message_type_count() > 0) { if (file_->message_type_count() > 0) {
printer->Print("#region Messages\n"); printer->Print("#region Messages\n");
for (int i = 0; i < file_->message_type_count(); i++) { for (int i = 0; i < file_->message_type_count(); i++) {
MessageGenerator messageGenerator(file_->message_type(i)); MessageGenerator messageGenerator(file_->message_type(i), this->options());
messageGenerator.Generate(printer); messageGenerator.Generate(printer);
} }
printer->Print("#endregion\n"); printer->Print("#endregion\n");

@ -43,7 +43,7 @@ namespace csharp {
class ReflectionClassGenerator : public SourceGeneratorBase { class ReflectionClassGenerator : public SourceGeneratorBase {
public: public:
ReflectionClassGenerator(const FileDescriptor* file); ReflectionClassGenerator(const FileDescriptor* file, const Options* options);
~ReflectionClassGenerator(); ~ReflectionClassGenerator();
void Generate(io::Printer* printer); void Generate(io::Printer* printer);
@ -56,7 +56,9 @@ class ReflectionClassGenerator : public SourceGeneratorBase {
void WriteIntroduction(io::Printer* printer); void WriteIntroduction(io::Printer* printer);
void WriteDescriptor(io::Printer* printer); void WriteDescriptor(io::Printer* printer);
void WriteGeneratedCodeInfo(const Descriptor* descriptor, io::Printer* printer, bool last); void WriteGeneratedCodeInfo(const Descriptor* descriptor,
io::Printer* printer,
bool last);
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ReflectionClassGenerator); GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ReflectionClassGenerator);
}; };

@ -48,8 +48,8 @@ namespace compiler {
namespace csharp { namespace csharp {
RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator( RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator(
const FieldDescriptor* descriptor, int fieldOrdinal) const FieldDescriptor* descriptor, int fieldOrdinal, const Options *options)
: FieldGeneratorBase(descriptor, fieldOrdinal) { : FieldGeneratorBase(descriptor, fieldOrdinal, options) {
} }
RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() { RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {

@ -45,7 +45,9 @@ namespace csharp {
// should probably have a RepeatedFieldGeneratorBase. // should probably have a RepeatedFieldGeneratorBase.
class RepeatedEnumFieldGenerator : public FieldGeneratorBase { class RepeatedEnumFieldGenerator : public FieldGeneratorBase {
public: public:
RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor,
int fieldOrdinal,
const Options *options);
~RepeatedEnumFieldGenerator(); ~RepeatedEnumFieldGenerator();
virtual void GenerateCloningCode(io::Printer* printer); virtual void GenerateCloningCode(io::Printer* printer);

@ -49,8 +49,8 @@ namespace compiler {
namespace csharp { namespace csharp {
RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator( RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
const FieldDescriptor* descriptor, int fieldOrdinal) const FieldDescriptor* descriptor, int fieldOrdinal, const Options *options)
: FieldGeneratorBase(descriptor, fieldOrdinal) { : FieldGeneratorBase(descriptor, fieldOrdinal, options) {
} }
RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() { RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {
@ -66,10 +66,12 @@ void RepeatedMessageFieldGenerator::GenerateMembers(io::Printer* printer) {
// "create single field generator for this repeated field" // "create single field generator for this repeated field"
// function, but it doesn't seem worth it for just this. // function, but it doesn't seem worth it for just this.
if (IsWrapperType(descriptor_)) { if (IsWrapperType(descriptor_)) {
scoped_ptr<FieldGeneratorBase> single_generator(new WrapperFieldGenerator(descriptor_, fieldOrdinal_)); scoped_ptr<FieldGeneratorBase> single_generator(
new WrapperFieldGenerator(descriptor_, fieldOrdinal_, this->options()));
single_generator->GenerateCodecCode(printer); single_generator->GenerateCodecCode(printer);
} else { } else {
scoped_ptr<FieldGeneratorBase> single_generator(new MessageFieldGenerator(descriptor_, fieldOrdinal_)); scoped_ptr<FieldGeneratorBase> single_generator(
new MessageFieldGenerator(descriptor_, fieldOrdinal_, this->options()));
single_generator->GenerateCodecCode(printer); single_generator->GenerateCodecCode(printer);
} }
printer->Print(";\n"); printer->Print(";\n");

@ -41,9 +41,13 @@ namespace protobuf {
namespace compiler { namespace compiler {
namespace csharp { namespace csharp {
struct Options;
class RepeatedMessageFieldGenerator : public FieldGeneratorBase { class RepeatedMessageFieldGenerator : public FieldGeneratorBase {
public: public:
RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
int fieldOrdinal,
const Options *options);
~RepeatedMessageFieldGenerator(); ~RepeatedMessageFieldGenerator();
virtual void GenerateCloningCode(io::Printer* printer); virtual void GenerateCloningCode(io::Printer* printer);

@ -48,8 +48,8 @@ namespace compiler {
namespace csharp { namespace csharp {
RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator( RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator(
const FieldDescriptor* descriptor, int fieldOrdinal) const FieldDescriptor* descriptor, int fieldOrdinal, const Options *options)
: FieldGeneratorBase(descriptor, fieldOrdinal) { : FieldGeneratorBase(descriptor, fieldOrdinal, options) {
} }
RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() { RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {

@ -43,7 +43,7 @@ namespace csharp {
class RepeatedPrimitiveFieldGenerator : public FieldGeneratorBase { class RepeatedPrimitiveFieldGenerator : public FieldGeneratorBase {
public: public:
RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal, const Options *options);
~RepeatedPrimitiveFieldGenerator(); ~RepeatedPrimitiveFieldGenerator();
virtual void GenerateCloningCode(io::Printer* printer); virtual void GenerateCloningCode(io::Printer* printer);

@ -39,14 +39,17 @@
#include <google/protobuf/compiler/csharp/csharp_source_generator_base.h> #include <google/protobuf/compiler/csharp/csharp_source_generator_base.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h> #include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/compiler/csharp/csharp_names.h>
#include <google/protobuf/compiler/csharp/csharp_options.h>
namespace google { namespace google {
namespace protobuf { namespace protobuf {
namespace compiler { namespace compiler {
namespace csharp { namespace csharp {
SourceGeneratorBase::SourceGeneratorBase(const FileDescriptor* descriptor) SourceGeneratorBase::SourceGeneratorBase(const FileDescriptor* descriptor,
: descriptor_(descriptor) { const Options *options)
: descriptor_(descriptor), options_(options) {
} }
SourceGeneratorBase::~SourceGeneratorBase() { SourceGeneratorBase::~SourceGeneratorBase() {
@ -60,6 +63,10 @@ std::string SourceGeneratorBase::class_access_level() {
return IsDescriptorProto(descriptor_) ? "internal" : "public"; // public_classes is always on. return IsDescriptorProto(descriptor_) ? "internal" : "public"; // public_classes is always on.
} }
const Options* SourceGeneratorBase::options() {
return this->options_;
}
} // namespace csharp } // namespace csharp
} // namespace compiler } // namespace compiler
} // namespace protobuf } // namespace protobuf

@ -40,17 +40,21 @@ namespace protobuf {
namespace compiler { namespace compiler {
namespace csharp { namespace csharp {
struct Options;
class SourceGeneratorBase { class SourceGeneratorBase {
protected: protected:
SourceGeneratorBase(const FileDescriptor* descriptor); SourceGeneratorBase(const FileDescriptor* descriptor, const Options* options);
virtual ~SourceGeneratorBase(); virtual ~SourceGeneratorBase();
std::string class_access_level(); std::string class_access_level();
const Options* options();
void WriteGeneratedCodeAttributes(io::Printer* printer); void WriteGeneratedCodeAttributes(io::Printer* printer);
private: private:
const FileDescriptor* descriptor_; const FileDescriptor* descriptor_;
const Options *options_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SourceGeneratorBase); GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SourceGeneratorBase);
}; };

@ -39,6 +39,7 @@
#include <google/protobuf/compiler/csharp/csharp_doc_comment.h> #include <google/protobuf/compiler/csharp/csharp_doc_comment.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h> #include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/compiler/csharp/csharp_options.h>
#include <google/protobuf/compiler/csharp/csharp_wrapper_field.h> #include <google/protobuf/compiler/csharp/csharp_wrapper_field.h>
namespace google { namespace google {
@ -47,8 +48,8 @@ namespace compiler {
namespace csharp { namespace csharp {
WrapperFieldGenerator::WrapperFieldGenerator(const FieldDescriptor* descriptor, WrapperFieldGenerator::WrapperFieldGenerator(const FieldDescriptor* descriptor,
int fieldOrdinal) int fieldOrdinal, const Options *options)
: FieldGeneratorBase(descriptor, fieldOrdinal) { : FieldGeneratorBase(descriptor, fieldOrdinal, options) {
variables_["has_property_check"] = name() + "_ != null"; variables_["has_property_check"] = name() + "_ != null";
variables_["has_not_property_check"] = name() + "_ == null"; variables_["has_not_property_check"] = name() + "_ == null";
const FieldDescriptor* wrapped_field = descriptor->message_type()->field(0); const FieldDescriptor* wrapped_field = descriptor->message_type()->field(0);
@ -151,9 +152,9 @@ void WrapperFieldGenerator::GenerateCodecCode(io::Printer* printer) {
} }
} }
WrapperOneofFieldGenerator::WrapperOneofFieldGenerator(const FieldDescriptor* descriptor, WrapperOneofFieldGenerator::WrapperOneofFieldGenerator(
int fieldOrdinal) const FieldDescriptor* descriptor, int fieldOrdinal, const Options *options)
: WrapperFieldGenerator(descriptor, fieldOrdinal) { : WrapperFieldGenerator(descriptor, fieldOrdinal, options) {
SetCommonOneofFieldVariables(&variables_); SetCommonOneofFieldVariables(&variables_);
} }

@ -41,9 +41,13 @@ namespace protobuf {
namespace compiler { namespace compiler {
namespace csharp { namespace csharp {
struct Options;
class WrapperFieldGenerator : public FieldGeneratorBase { class WrapperFieldGenerator : public FieldGeneratorBase {
public: public:
WrapperFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); WrapperFieldGenerator(const FieldDescriptor* descriptor,
int fieldOrdinal,
const Options *options);
~WrapperFieldGenerator(); ~WrapperFieldGenerator();
virtual void GenerateCodecCode(io::Printer* printer); virtual void GenerateCodecCode(io::Printer* printer);
@ -65,7 +69,9 @@ class WrapperFieldGenerator : public FieldGeneratorBase {
class WrapperOneofFieldGenerator : public WrapperFieldGenerator { class WrapperOneofFieldGenerator : public WrapperFieldGenerator {
public: public:
WrapperOneofFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); WrapperOneofFieldGenerator(const FieldDescriptor* descriptor,
int fieldOrdinal,
const Options *options);
~WrapperOneofFieldGenerator(); ~WrapperOneofFieldGenerator();
virtual void GenerateMembers(io::Printer* printer); virtual void GenerateMembers(io::Printer* printer);

@ -72,8 +72,9 @@ void EnumGenerator::GenerateHeader(io::Printer* printer) {
"\n", "\n",
"name", name_); "name", name_);
printer->Print("$comments$typedef GPB_ENUM($name$) {\n", printer->Print("$comments$typedef$deprecated_attribute$ GPB_ENUM($name$) {\n",
"comments", enum_comments, "comments", enum_comments,
"deprecated_attribute", GetOptionalDeprecatedAttribute(descriptor_),
"name", name_); "name", name_);
printer->Indent(); printer->Indent();
@ -99,8 +100,9 @@ void EnumGenerator::GenerateHeader(io::Printer* printer) {
} }
printer->Print( printer->Print(
"$name$ = $value$,\n", "$name$$deprecated_attribute$ = $value$,\n",
"name", EnumValueName(all_values_[i]), "name", EnumValueName(all_values_[i]),
"deprecated_attribute", GetOptionalDeprecatedAttribute(all_values_[i]),
"value", SimpleItoa(all_values_[i]->number())); "value", SimpleItoa(all_values_[i]->number()));
} }
printer->Outdent(); printer->Outdent();

@ -78,6 +78,7 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
classname + "_FieldNumber_" + capitalized_name; classname + "_FieldNumber_" + capitalized_name;
(*variables)["field_number"] = SimpleItoa(descriptor->number()); (*variables)["field_number"] = SimpleItoa(descriptor->number());
(*variables)["field_type"] = GetCapitalizedType(descriptor); (*variables)["field_type"] = GetCapitalizedType(descriptor);
(*variables)["deprecated_attribute"] = GetOptionalDeprecatedAttribute(descriptor);
std::vector<string> field_flags; std::vector<string> field_flags;
if (descriptor->is_repeated()) field_flags.push_back("GPBFieldRepeated"); if (descriptor->is_repeated()) field_flags.push_back("GPBFieldRepeated");
if (descriptor->is_required()) field_flags.push_back("GPBFieldRequired"); if (descriptor->is_required()) field_flags.push_back("GPBFieldRequired");
@ -266,12 +267,12 @@ void SingleFieldGenerator::GeneratePropertyDeclaration(
printer->Print(variables_, "$comments$"); printer->Print(variables_, "$comments$");
printer->Print( printer->Print(
variables_, variables_,
"@property(nonatomic, readwrite) $property_type$ $name$;\n" "@property(nonatomic, readwrite) $property_type$ $name$$deprecated_attribute$;\n"
"\n"); "\n");
if (WantsHasProperty()) { if (WantsHasProperty()) {
printer->Print( printer->Print(
variables_, variables_,
"@property(nonatomic, readwrite) BOOL has$capitalized_name$;\n"); "@property(nonatomic, readwrite) BOOL has$capitalized_name$$deprecated_attribute$;\n");
} }
} }
@ -330,18 +331,18 @@ void ObjCObjFieldGenerator::GeneratePropertyDeclaration(
printer->Print(variables_, "$comments$"); printer->Print(variables_, "$comments$");
printer->Print( printer->Print(
variables_, variables_,
"@property(nonatomic, readwrite, $property_storage_attribute$, null_resettable) $property_type$ *$name$$storage_attribute$;\n"); "@property(nonatomic, readwrite, $property_storage_attribute$, null_resettable) $property_type$ *$name$$storage_attribute$$deprecated_attribute$;\n");
if (WantsHasProperty()) { if (WantsHasProperty()) {
printer->Print( printer->Print(
variables_, variables_,
"/// Test to see if @c $name$ has been set.\n" "/// Test to see if @c $name$ has been set.\n"
"@property(nonatomic, readwrite) BOOL has$capitalized_name$;\n"); "@property(nonatomic, readwrite) BOOL has$capitalized_name$$deprecated_attribute$;\n");
} }
if (IsInitName(variables_.find("name")->second)) { if (IsInitName(variables_.find("name")->second)) {
// If property name starts with init we need to annotate it to get past ARC. // If property name starts with init we need to annotate it to get past ARC.
// http://stackoverflow.com/questions/18723226/how-do-i-annotate-an-objective-c-property-with-an-objc-method-family/18723227#18723227 // http://stackoverflow.com/questions/18723226/how-do-i-annotate-an-objective-c-property-with-an-objc-method-family/18723227#18723227
printer->Print(variables_, printer->Print(variables_,
"- ($property_type$ *)$name$ GPB_METHOD_FAMILY_NONE;\n"); "- ($property_type$ *)$name$ GPB_METHOD_FAMILY_NONE$deprecated_attribute$;\n");
} }
printer->Print("\n"); printer->Print("\n");
} }
@ -385,14 +386,14 @@ void RepeatedFieldGenerator::GeneratePropertyDeclaration(
variables_, variables_,
"$comments$" "$comments$"
"$array_comment$" "$array_comment$"
"@property(nonatomic, readwrite, strong, null_resettable) $array_property_type$ *$name$$storage_attribute$;\n" "@property(nonatomic, readwrite, strong, null_resettable) $array_property_type$ *$name$$storage_attribute$$deprecated_attribute$;\n"
"/// The number of items in @c $name$ without causing the array to be created.\n" "/// The number of items in @c $name$ without causing the array to be created.\n"
"@property(nonatomic, readonly) NSUInteger $name$_Count;\n"); "@property(nonatomic, readonly) NSUInteger $name$_Count$deprecated_attribute$;\n");
if (IsInitName(variables_.find("name")->second)) { if (IsInitName(variables_.find("name")->second)) {
// If property name starts with init we need to annotate it to get past ARC. // If property name starts with init we need to annotate it to get past ARC.
// http://stackoverflow.com/questions/18723226/how-do-i-annotate-an-objective-c-property-with-an-objc-method-family/18723227#18723227 // http://stackoverflow.com/questions/18723226/how-do-i-annotate-an-objective-c-property-with-an-objc-method-family/18723227#18723227
printer->Print(variables_, printer->Print(variables_,
"- ($array_property_type$ *)$name$ GPB_METHOD_FAMILY_NONE;\n"); "- ($array_property_type$ *)$name$ GPB_METHOD_FAMILY_NONE$deprecated_attribute$;\n");
} }
printer->Print("\n"); printer->Print("\n");
} }

@ -115,6 +115,9 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
printer->Print( printer->Print(
"// @@protoc_insertion_point(imports)\n" "// @@protoc_insertion_point(imports)\n"
"\n" "\n"
"#pragma clang diagnostic push\n"
"#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n"
"\n"
"CF_EXTERN_C_BEGIN\n" "CF_EXTERN_C_BEGIN\n"
"\n"); "\n");
@ -189,6 +192,8 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
"\n" "\n"
"CF_EXTERN_C_END\n" "CF_EXTERN_C_END\n"
"\n" "\n"
"#pragma clang diagnostic pop\n"
"\n"
"// @@protoc_insertion_point(global_scope)\n"); "// @@protoc_insertion_point(global_scope)\n");
} }
@ -216,6 +221,9 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
} }
printer->Print( printer->Print(
"// @@protoc_insertion_point(imports)\n" "// @@protoc_insertion_point(imports)\n"
"\n"
"#pragma clang diagnostic push\n"
"#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n"
"\n"); "\n");
printer->Print( printer->Print(
@ -342,6 +350,8 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
} }
printer->Print( printer->Print(
"\n"
"#pragma clang diagnostic pop\n"
"\n" "\n"
"// @@protoc_insertion_point(global_scope)\n"); "// @@protoc_insertion_point(global_scope)\n");
} }

@ -133,6 +133,22 @@ enum ObjectiveCType {
OBJECTIVECTYPE_MESSAGE OBJECTIVECTYPE_MESSAGE
}; };
template<class TDescriptor>
string GetOptionalDeprecatedAttribute(const TDescriptor* descriptor, bool preSpace = true, bool postNewline = false) {
if (descriptor->options().deprecated()) {
string result = "DEPRECATED_ATTRIBUTE";
if (preSpace) {
result.insert(0, " ");
}
if (postNewline) {
result.append("\n");
}
return result;
} else {
return "";
}
}
string GetCapitalizedType(const FieldDescriptor* field); string GetCapitalizedType(const FieldDescriptor* field);
ObjectiveCType GetObjectiveCType(FieldDescriptor::Type field_type); ObjectiveCType GetObjectiveCType(FieldDescriptor::Type field_type);

@ -321,8 +321,9 @@ void MessageGenerator::GenerateMessageHeader(io::Printer* printer) {
} }
printer->Print( printer->Print(
"$comments$@interface $classname$ : GPBMessage\n\n", "$comments$$deprecated_attribute$@interface $classname$ : GPBMessage\n\n",
"classname", class_name_, "classname", class_name_,
"deprecated_attribute", GetOptionalDeprecatedAttribute(descriptor_, false, true),
"comments", message_comments); "comments", message_comments);
vector<char> seen_oneofs(descriptor_->oneof_decl_count(), 0); vector<char> seen_oneofs(descriptor_->oneof_decl_count(), 0);

@ -253,6 +253,12 @@ class DynamicMessage : public Message {
DynamicMessage(const TypeInfo* type_info); DynamicMessage(const TypeInfo* type_info);
~DynamicMessage(); ~DynamicMessage();
#ifndef _MSC_VER
void operator delete(void *p) {
::operator delete(p); // non-sized deallocation
}
#endif
// Called on the prototype after construction to initialize message fields. // Called on the prototype after construction to initialize message fields.
void CrossLinkPrototypes(); void CrossLinkPrototypes();

Loading…
Cancel
Save