• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 #include "google/protobuf/compiler/objectivec/oneof.h"
9 
10 #include <string>
11 
12 #include "absl/strings/str_cat.h"
13 #include "google/protobuf/compiler/objectivec/helpers.h"
14 #include "google/protobuf/compiler/objectivec/names.h"
15 #include "google/protobuf/compiler/objectivec/options.h"
16 #include "google/protobuf/descriptor.h"
17 #include "google/protobuf/io/printer.h"
18 
19 namespace google {
20 namespace protobuf {
21 namespace compiler {
22 namespace objectivec {
23 
OneofGenerator(const OneofDescriptor * descriptor,const GenerationOptions & generation_options)24 OneofGenerator::OneofGenerator(const OneofDescriptor* descriptor,
25                                const GenerationOptions& generation_options)
26     : descriptor_(descriptor), generation_options_(generation_options) {
27   variables_["enum_name"] = OneofEnumName(descriptor_);
28   variables_["name"] = OneofName(descriptor_);
29   variables_["capitalized_name"] = OneofNameCapitalized(descriptor_);
30   variables_["raw_index"] = absl::StrCat(descriptor_->index());
31   const Descriptor* msg_descriptor = descriptor_->containing_type();
32   variables_["owning_message_class"] = ClassName(msg_descriptor);
33 }
34 
SetOneofIndexBase(int index_base)35 void OneofGenerator::SetOneofIndexBase(int index_base) {
36   int index = descriptor_->index() + index_base;
37   // Flip the sign to mark it as a oneof.
38   variables_["index"] = absl::StrCat(-index);
39 }
40 
GenerateCaseEnum(io::Printer * printer) const41 void OneofGenerator::GenerateCaseEnum(io::Printer* printer) const {
42   auto vars = printer->WithVars(variables_);
43   printer->Emit({{"cases",
44                   [&] {
45                     for (int j = 0; j < descriptor_->field_count(); j++) {
46                       const FieldDescriptor* field = descriptor_->field(j);
47                       printer->Emit(
48                           {{"field_name", FieldNameCapitalized(field)},
49                            {"field_number", field->number()}},
50                           R"objc(
51                             $enum_name$_$field_name$ = $field_number$,
52                           )objc");
53                     }
54                   }}},
55                 R"objc(
56                   typedef GPB_ENUM($enum_name$) {
57                     $enum_name$_GPBUnsetOneOfCase = 0,
58                     $cases$
59                   };
60                 )objc");
61   printer->Emit("\n");
62 }
63 
GeneratePublicCasePropertyDeclaration(io::Printer * printer) const64 void OneofGenerator::GeneratePublicCasePropertyDeclaration(
65     io::Printer* printer) const {
66   auto vars = printer->WithVars(variables_);
67   printer->Emit({{"comments",
68                   [&] {
69                     EmitCommentsString(printer, generation_options_,
70                                        descriptor_);
71                   }}},
72                 R"objc(
73                   $comments$;
74                   @property(nonatomic, readonly) $enum_name$ $name$OneOfCase;
75                 )objc");
76   printer->Emit("\n");
77 }
78 
GenerateClearFunctionDeclaration(io::Printer * printer) const79 void OneofGenerator::GenerateClearFunctionDeclaration(
80     io::Printer* printer) const {
81   auto vars = printer->WithVars(variables_);
82   printer->Emit(R"objc(
83       /**
84        * Clears whatever value was set for the oneof '$name$'.
85        **/
86       void $owning_message_class$_Clear$capitalized_name$OneOfCase($owning_message_class$ *message);
87     )objc");
88 }
89 
GeneratePropertyImplementation(io::Printer * printer) const90 void OneofGenerator::GeneratePropertyImplementation(
91     io::Printer* printer) const {
92   auto vars = printer->WithVars(variables_);
93   printer->Emit(R"objc(
94     @dynamic $name$OneOfCase;
95   )objc");
96 }
97 
GenerateClearFunctionImplementation(io::Printer * printer) const98 void OneofGenerator::GenerateClearFunctionImplementation(
99     io::Printer* printer) const {
100   auto vars = printer->WithVars(variables_);
101   printer->Emit(R"objc(
102     void $owning_message_class$_Clear$capitalized_name$OneOfCase($owning_message_class$ *message) {
103       GPBDescriptor *descriptor = [$owning_message_class$ descriptor];
104       GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:$raw_index$];
105       GPBClearOneof(message, oneof);
106     }
107   )objc");
108 }
109 
DescriptorName() const110 std::string OneofGenerator::DescriptorName() const {
111   return variables_.find("name")->second;
112 }
113 
HasIndexAsString() const114 std::string OneofGenerator::HasIndexAsString() const {
115   return variables_.find("index")->second;
116 }
117 
118 }  // namespace objectivec
119 }  // namespace compiler
120 }  // namespace protobuf
121 }  // namespace google
122