Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 89 additions & 3 deletions src/google/protobuf/compiler/objectivec/extension.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ namespace objectivec {
using Sub = ::google::protobuf::io::Printer::Sub;

ExtensionGenerator::ExtensionGenerator(
absl::string_view root_or_message_class_name,
const FieldDescriptor* descriptor,
const GenerationOptions& generation_options)
: root_or_message_class_name_(root_or_message_class_name),
: root_or_message_class_name_(ExtensionClassName(descriptor)),
method_name_(ExtensionMethodName(descriptor)),
function_name_(ExtensionFunctionName(descriptor)),
descriptor_(descriptor),
generation_options_(generation_options) {
ABSL_CHECK(!descriptor->is_map())
Expand All @@ -50,7 +50,24 @@ ExtensionGenerator::ExtensionGenerator(
}
}

void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) const {
void ExtensionGenerator::GenerateFunctionsHeader(io::Printer* printer) const {
printer->Emit(
{Sub("function_name", function_name_).AnnotatedAs(descriptor_),
{"comments",
[&] { EmitCommentsString(printer, generation_options_, descriptor_); }},
{"storage_attribute",
IsRetainedName(function_name_) ? "NS_RETURNS_NOT_RETAINED" : ""},
{"deprecated_attribute",
// Unlike normal message fields, check if the file for the extension was
// deprecated.
GetOptionalDeprecatedAttribute(descriptor_, descriptor_->file())}},
R"objc(
$comments$
GPBExtensionDescriptor *$function_name$(void)$ storage_attribute$$ deprecated_attribute$;
)objc");
}

void ExtensionGenerator::GenerateMethodsHeader(io::Printer* printer) const {
printer->Emit(
{Sub("method_name", method_name_).AnnotatedAs(descriptor_),
{"comments",
Expand All @@ -67,6 +84,22 @@ void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) const {
)objc");
}

void ExtensionGenerator::GenerateAddExtensionToRegistryFunctionCall(
io::Printer* printer) const {
printer->Emit({{"function_name", function_name_}},
R"objc(
[registry addExtension:$function_name$()];
)objc");
}

void ExtensionGenerator::GenerateAddExtensionToGlobalRegistryFunctionCall(
io::Printer* printer) const {
printer->Emit({{"function_name", function_name_}},
R"objc(
[self globallyRegisterExtension:$function_name$()];
)objc");
}

void ExtensionGenerator::GenerateStaticVariablesInitialization(
io::Printer* printer) const {
const std::string containing_type = ClassName(descriptor_->containing_type());
Expand Down Expand Up @@ -109,6 +142,59 @@ void ExtensionGenerator::GenerateStaticVariablesInitialization(
)objc");
}

void ExtensionGenerator::GenerateDescriptorFunction(
io::Printer* printer) const {
const std::string containing_type = ClassName(descriptor_->containing_type());
ObjectiveCType objc_type = GetObjectiveCType(descriptor_);

std::vector<std::string> options;
if (descriptor_->is_repeated()) options.push_back("GPBExtensionRepeated");
if (descriptor_->is_packed()) options.push_back("GPBExtensionPacked");

printer->Emit(
{{"default",
descriptor_->is_repeated() ? "nil" : DefaultValue(descriptor_)},
{"default_name", GPBGenericValueFieldName(descriptor_)},
{"enum_desc_func_name",
objc_type == OBJECTIVECTYPE_ENUM
? absl::StrCat(EnumName(descriptor_->enum_type()),
"_EnumDescriptor")
: "NULL"},
{"extended_type", ObjCClass(containing_type)},
{"extension_type",
absl::StrCat("GPBDataType", GetCapitalizedType(descriptor_))},
{"method_name", method_name_},
{"function_name", function_name_},
{"number", descriptor_->number()},
{"options", BuildFlagsString(FLAGTYPE_EXTENSION, options)},
{"root_or_message_class_name", root_or_message_class_name_},
{"type", objc_type == OBJECTIVECTYPE_MESSAGE
? ObjCClass(ClassName(descriptor_->message_type()))
: "Nil"}},
R"objc(
GPBExtensionDescriptor *$function_name$(void) {
static GPBExtensionDescription description = {
.defaultValue.$default_name$ = $default$,
.singletonName = GPBStringifySymbol($root_or_message_class_name$) "_$method_name$",
.extendedClass.clazz = $extended_type$,
.messageOrGroupClass.clazz = $type$,
.enumDescriptorFunc = $enum_desc_func_name$,
.fieldNumber = $number$,
.dataType = $extension_type$,
.options = $options$,
};
static GPBExtensionDescriptor *extension;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
extension =
[[GPBExtensionDescriptor alloc] initWithExtensionDescription:&description
runtimeSupport:&$google_protobuf_runtime_support$];
}
return extension;
}
)objc");
}

void ExtensionGenerator::DetermineObjectiveCClassDefinitions(
absl::btree_set<std::string>* fwd_decls) const {
std::string extended_type = ClassName(descriptor_->containing_type());
Expand Down
13 changes: 10 additions & 3 deletions src/google/protobuf/compiler/objectivec/extension.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,22 @@ namespace objectivec {

class ExtensionGenerator {
public:
ExtensionGenerator(absl::string_view root_or_message_class_name,
const FieldDescriptor* descriptor,
ExtensionGenerator(const FieldDescriptor* descriptor,
const GenerationOptions& generation_options);
~ExtensionGenerator() = default;

ExtensionGenerator(const ExtensionGenerator&) = delete;
ExtensionGenerator& operator=(const ExtensionGenerator&) = delete;

void GenerateMembersHeader(io::Printer* printer) const;
void GenerateFunctionsHeader(io::Printer* printer) const;
void GenerateMethodsHeader(io::Printer* printer) const;

void GenerateStaticVariablesInitialization(io::Printer* printer) const;
void GenerateDescriptorFunction(io::Printer* printer) const;
void GenerateAddExtensionToRegistryFunctionCall(io::Printer* printer) const;
void GenerateAddExtensionToGlobalRegistryFunctionCall(
io::Printer* printer) const;

void DetermineObjectiveCClassDefinitions(
absl::btree_set<std::string>* fwd_decls) const;
void DetermineNeededFiles(
Expand All @@ -42,6 +48,7 @@ class ExtensionGenerator {
private:
std::string root_or_message_class_name_;
std::string method_name_;
std::string function_name_;
const FieldDescriptor* descriptor_;
const GenerationOptions& generation_options_;
};
Expand Down
Loading
Loading