1 | // Protocol Buffers - Google's data interchange format |
2 | // Copyright 2008 Google Inc. All rights reserved. |
3 | // https://developers.google.com/protocol-buffers/ |
4 | // |
5 | // Redistribution and use in source and binary forms, with or without |
6 | // modification, are permitted provided that the following conditions are |
7 | // met: |
8 | // |
9 | // * Redistributions of source code must retain the above copyright |
10 | // notice, this list of conditions and the following disclaimer. |
11 | // * Redistributions in binary form must reproduce the above |
12 | // copyright notice, this list of conditions and the following disclaimer |
13 | // in the documentation and/or other materials provided with the |
14 | // distribution. |
15 | // * Neither the name of Google Inc. nor the names of its |
16 | // contributors may be used to endorse or promote products derived from |
17 | // this software without specific prior written permission. |
18 | // |
19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 | |
31 | #include <map> |
32 | #include <string> |
33 | |
34 | #include <google/protobuf/compiler/objectivec/objectivec_oneof.h> |
35 | #include <google/protobuf/compiler/objectivec/objectivec_helpers.h> |
36 | #include <google/protobuf/io/printer.h> |
37 | #include <google/protobuf/stubs/strutil.h> |
38 | |
39 | namespace google { |
40 | namespace protobuf { |
41 | namespace compiler { |
42 | namespace objectivec { |
43 | |
44 | OneofGenerator::OneofGenerator(const OneofDescriptor* descriptor) |
45 | : descriptor_(descriptor) { |
46 | variables_["enum_name" ] = OneofEnumName(descriptor: descriptor_); |
47 | variables_["name" ] = OneofName(descriptor: descriptor_); |
48 | variables_["capitalized_name" ] = OneofNameCapitalized(descriptor: descriptor_); |
49 | variables_["raw_index" ] = StrCat(a: descriptor_->index()); |
50 | const Descriptor* msg_descriptor = descriptor_->containing_type(); |
51 | variables_["owning_message_class" ] = ClassName(descriptor: msg_descriptor); |
52 | |
53 | std::string ; |
54 | SourceLocation location; |
55 | if (descriptor_->GetSourceLocation(out_location: &location)) { |
56 | comments = BuildCommentsString(location, prefer_single_line: true); |
57 | } else { |
58 | comments = "" ; |
59 | } |
60 | variables_["comments" ] = comments; |
61 | } |
62 | |
63 | OneofGenerator::~OneofGenerator() {} |
64 | |
65 | void OneofGenerator::SetOneofIndexBase(int index_base) { |
66 | int index = descriptor_->index() + index_base; |
67 | // Flip the sign to mark it as a oneof. |
68 | variables_["index" ] = StrCat(a: -index); |
69 | } |
70 | |
71 | void OneofGenerator::GenerateCaseEnum(io::Printer* printer) { |
72 | printer->Print( |
73 | variables: variables_, |
74 | text: "typedef GPB_ENUM($enum_name$) {\n" ); |
75 | printer->Indent(); |
76 | printer->Print( |
77 | variables: variables_, |
78 | text: "$enum_name$_GPBUnsetOneOfCase = 0,\n" ); |
79 | std::string enum_name = variables_["enum_name" ]; |
80 | for (int j = 0; j < descriptor_->field_count(); j++) { |
81 | const FieldDescriptor* field = descriptor_->field(index: j); |
82 | std::string field_name = FieldNameCapitalized(field); |
83 | printer->Print( |
84 | text: "$enum_name$_$field_name$ = $field_number$,\n" , |
85 | args: "enum_name" , args: enum_name, |
86 | args: "field_name" , args: field_name, |
87 | args: "field_number" , args: StrCat(a: field->number())); |
88 | } |
89 | printer->Outdent(); |
90 | printer->Print( |
91 | text: "};\n" |
92 | "\n" ); |
93 | } |
94 | |
95 | void OneofGenerator::GeneratePublicCasePropertyDeclaration( |
96 | io::Printer* printer) { |
97 | printer->Print( |
98 | variables: variables_, |
99 | text: "$comments$" |
100 | "@property(nonatomic, readonly) $enum_name$ $name$OneOfCase;\n" |
101 | "\n" ); |
102 | } |
103 | |
104 | void OneofGenerator::GenerateClearFunctionDeclaration(io::Printer* printer) { |
105 | printer->Print( |
106 | variables: variables_, |
107 | text: "/**\n" |
108 | " * Clears whatever value was set for the oneof '$name$'.\n" |
109 | " **/\n" |
110 | "void $owning_message_class$_Clear$capitalized_name$OneOfCase($owning_message_class$ *message);\n" ); |
111 | } |
112 | |
113 | void OneofGenerator::GeneratePropertyImplementation(io::Printer* printer) { |
114 | printer->Print( |
115 | variables: variables_, |
116 | text: "@dynamic $name$OneOfCase;\n" ); |
117 | } |
118 | |
119 | void OneofGenerator::GenerateClearFunctionImplementation(io::Printer* printer) { |
120 | printer->Print( |
121 | variables: variables_, |
122 | text: "void $owning_message_class$_Clear$capitalized_name$OneOfCase($owning_message_class$ *message) {\n" |
123 | " GPBDescriptor *descriptor = [$owning_message_class$ descriptor];\n" |
124 | " GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:$raw_index$];\n" |
125 | " GPBClearOneof(message, oneof);\n" |
126 | "}\n" ); |
127 | } |
128 | |
129 | std::string OneofGenerator::DescriptorName(void) const { |
130 | return variables_.find(x: "name" )->second; |
131 | } |
132 | |
133 | std::string OneofGenerator::HasIndexAsString(void) const { |
134 | return variables_.find(x: "index" )->second; |
135 | } |
136 | |
137 | } // namespace objectivec |
138 | } // namespace compiler |
139 | } // namespace protobuf |
140 | } // namespace google |
141 | |