Skip to content

Commit b146d14

Browse files
thomasvlcopybara-github
authored andcommitted
[ObjC] Improve handing of the WKT ObjC Category additions.
Include a comment in the generated header about there being helpers in GPBWellKnowTypes.h Generate some extra code for the WKTs that have categories to help ensure the categories get linked so developers don't have to use -ObjC in some cases. PiperOrigin-RevId: 589179237
1 parent cca8a7c commit b146d14

File tree

10 files changed

+114
-0
lines changed

10 files changed

+114
-0
lines changed

objectivec/GPBAny.pbobjc.h

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

objectivec/GPBAny.pbobjc.m

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

objectivec/GPBDuration.pbobjc.h

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

objectivec/GPBDuration.pbobjc.m

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

objectivec/GPBTimestamp.pbobjc.h

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

objectivec/GPBTimestamp.pbobjc.m

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/google/protobuf/compiler/objectivec/file.cc

+36
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#include "absl/log/absl_check.h"
2323
#include "absl/strings/str_cat.h"
2424
#include "absl/strings/str_join.h"
25+
#include "absl/strings/string_view.h"
26+
#include "google/protobuf/compiler/code_generator.h"
2527
#include "google/protobuf/compiler/objectivec/enum.h"
2628
#include "google/protobuf/compiler/objectivec/extension.h"
2729
#include "google/protobuf/compiler/objectivec/helpers.h"
@@ -139,6 +141,27 @@ void MakeDescriptors(
139141
}
140142
}
141143

144+
void EmitLinkWKTs(absl::string_view name, io::Printer* p) {
145+
absl::string_view::size_type last_slash = name.rfind('/');
146+
std::string basename;
147+
if (last_slash == absl::string_view::npos) {
148+
basename = std::string(name);
149+
} else {
150+
basename = std::string(name.substr(last_slash + 1));
151+
}
152+
153+
p->Emit({{"basename", StripProto(basename)}},
154+
R"objc(
155+
// This is to help make sure that the GPBWellKnownTypes.* categories get linked and
156+
// developers do not have to use the `-ObjC` linker flag. More information
157+
// here: https://medium.com/ios-os-x-development/categories-in-static-libraries-78e41f8ddb96
158+
__attribute__((used)) static NSString* $basename$_importCategories () {
159+
return GPBWellKnownTypesErrorDomain;
160+
}
161+
)objc");
162+
p->Emit("\n");
163+
}
164+
142165
void EmitSourceFwdDecls(const absl::btree_set<std::string>& fwd_decls,
143166
io::Printer* p) {
144167
if (fwd_decls.empty()) {
@@ -385,6 +408,10 @@ void FileGenerator::GenerateSource(io::Printer* p) const {
385408
EmitRootImplementation(p, deps_with_extensions);
386409
EmitFileDescription(p);
387410

411+
if (is_bundled_proto_ && HasWKTWithObjCCategory(file_)) {
412+
EmitLinkWKTs(file_->name(), p);
413+
}
414+
388415
for (const auto& generator : enum_generators_) {
389416
generator->GenerateSource(p);
390417
}
@@ -395,6 +422,8 @@ void FileGenerator::GenerateSource(io::Printer* p) const {
395422
}
396423

397424
void FileGenerator::GenerateGlobalSource(io::Printer* p) const {
425+
ABSL_CHECK(!is_bundled_proto_)
426+
<< "Bundled protos aren't expected to use multi source generation.";
398427
std::vector<const FileDescriptor*> deps_with_extensions =
399428
common_state_->CollectMinimalFileDepsContainingExtensions(file_);
400429
GeneratedFileOptions file_options;
@@ -416,6 +445,8 @@ void FileGenerator::GenerateGlobalSource(io::Printer* p) const {
416445
}
417446

418447
void FileGenerator::GenerateSourceForEnums(io::Printer* p) const {
448+
ABSL_CHECK(!is_bundled_proto_)
449+
<< "Bundled protos aren't expected to use multi source generation.";
419450
// Enum implementation uses atomic in the generated code.
420451
GeneratedFileOptions file_options;
421452
file_options.extra_system_headers.push_back("stdatomic.h");
@@ -428,6 +459,8 @@ void FileGenerator::GenerateSourceForEnums(io::Printer* p) const {
428459
}
429460

430461
void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* p) const {
462+
ABSL_CHECK(!is_bundled_proto_)
463+
<< "Bundled protos aren't expected to use multi source generation.";
431464
const auto& generator = message_generators_[idx];
432465

433466
absl::btree_set<std::string> fwd_decls;
@@ -485,6 +518,9 @@ void FileGenerator::GenerateFile(io::Printer* p, GeneratedFileType file_type,
485518
break;
486519
case GeneratedFileType::kSource:
487520
import_writer.AddRuntimeImport("GPBProtocolBuffers_RuntimeSupport.h");
521+
if (is_bundled_proto_ && HasWKTWithObjCCategory(file_)) {
522+
import_writer.AddRuntimeImport("GPBWellKnownTypes.h");
523+
}
488524
import_writer.AddFile(file_, header_extension);
489525
if (HeadersUseForwardDeclarations()) {
490526
if (generation_options_.generate_minimal_imports) {

src/google/protobuf/compiler/objectivec/helpers.cc

+28
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <string>
1414
#include <vector>
1515

16+
#include "absl/log/absl_check.h"
1617
#include "absl/log/absl_log.h"
1718
#include "absl/strings/ascii.h"
1819
#include "absl/strings/escaping.h"
@@ -393,6 +394,33 @@ void EmitCommentsString(io::Printer* printer, const SourceLocation& location,
393394
)");
394395
}
395396

397+
bool HasWKTWithObjCCategory(const FileDescriptor* file) {
398+
// We don't check the name prefix or proto package because some files
399+
// (descriptor.proto), aren't shipped generated by the library, so this
400+
// seems to be the safest way to only catch the ones shipped.
401+
const std::string name = file->name();
402+
if (name == "google/protobuf/any.proto" ||
403+
name == "google/protobuf/duration.proto" ||
404+
name == "google/protobuf/timestamp.proto") {
405+
ABSL_DCHECK(IsProtobufLibraryBundledProtoFile(file));
406+
return true;
407+
}
408+
return false;
409+
}
410+
411+
bool IsWKTWithObjCCategory(const Descriptor* descriptor) {
412+
if (!HasWKTWithObjCCategory(descriptor->file())) {
413+
return false;
414+
}
415+
const std::string full_name = descriptor->full_name();
416+
if (full_name == "google.protobuf.Any" ||
417+
full_name == "google.protobuf.Duration" ||
418+
full_name == "google.protobuf.Timestamp") {
419+
return true;
420+
}
421+
return false;
422+
}
423+
396424
} // namespace objectivec
397425
} // namespace compiler
398426
} // namespace protobuf

src/google/protobuf/compiler/objectivec/helpers.h

+5
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,11 @@ std::string GetOptionalDeprecatedAttribute(
148148
}
149149
}
150150

151+
// Helpers to identify the WellKnownType files/messages that get an Objective-C
152+
// category within the runtime to add helpers.
153+
bool HasWKTWithObjCCategory(const FileDescriptor* file);
154+
bool IsWKTWithObjCCategory(const Descriptor* descriptor);
155+
151156
} // namespace objectivec
152157
} // namespace compiler
153158
} // namespace protobuf

src/google/protobuf/compiler/objectivec/message.cc

+12
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,17 @@ void MessageGenerator::GenerateMessageHeader(io::Printer* printer) const {
336336
}
337337
field_generators_.get(field).GeneratePropertyDeclaration(printer);
338338
}
339+
}},
340+
{"wkt_extra",
341+
[&] {
342+
if (!IsWKTWithObjCCategory(descriptor_)) {
343+
return;
344+
}
345+
printer->Emit(R"objc(
346+
// NOTE: There are some Objective-C specific methods/properties in
347+
// GPBWellKnownTypes.h that will likey be useful.
348+
)objc");
349+
printer->Emit("\n");
339350
}}},
340351
R"objc(
341352
#pragma mark - $classname$
@@ -347,6 +358,7 @@ void MessageGenerator::GenerateMessageHeader(io::Printer* printer) const {
347358
GPB_FINAL @interface $classname$ : GPBMessage
348359
349360
$message_properties$
361+
$wkt_extra$
350362
@end
351363
)objc");
352364
printer->Emit("\n");

0 commit comments

Comments
 (0)