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/message_field.h"
9
10 #include <string>
11
12 #include "absl/container/btree_set.h"
13 #include "absl/container/flat_hash_map.h"
14 #include "absl/container/flat_hash_set.h"
15 #include "absl/strings/str_cat.h"
16 #include "absl/strings/string_view.h"
17 #include "google/protobuf/compiler/objectivec/field.h"
18 #include "google/protobuf/compiler/objectivec/helpers.h"
19 #include "google/protobuf/compiler/objectivec/names.h"
20 #include "google/protobuf/compiler/objectivec/options.h"
21 #include "google/protobuf/descriptor.h"
22
23 namespace google {
24 namespace protobuf {
25 namespace compiler {
26 namespace objectivec {
27
28 namespace {
29
SetMessageVariables(const FieldDescriptor * descriptor,absl::flat_hash_map<absl::string_view,std::string> * variables)30 void SetMessageVariables(
31 const FieldDescriptor* descriptor,
32 absl::flat_hash_map<absl::string_view, std::string>* variables) {
33 const std::string& message_type = ClassName(descriptor->message_type());
34 const std::string& containing_class =
35 ClassName(descriptor->containing_type());
36 (*variables)["msg_type"] = message_type;
37 (*variables)["containing_class"] = containing_class;
38 (*variables)["dataTypeSpecific_value"] = ObjCClass(message_type);
39 }
40
41 } // namespace
42
MessageFieldGenerator(const FieldDescriptor * descriptor,const GenerationOptions & generation_options)43 MessageFieldGenerator::MessageFieldGenerator(
44 const FieldDescriptor* descriptor,
45 const GenerationOptions& generation_options)
46 : ObjCObjFieldGenerator(descriptor, generation_options) {
47 SetMessageVariables(descriptor, &variables_);
48 }
49
DetermineForwardDeclarations(absl::btree_set<std::string> * fwd_decls,bool include_external_types) const50 void MessageFieldGenerator::DetermineForwardDeclarations(
51 absl::btree_set<std::string>* fwd_decls,
52 bool include_external_types) const {
53 ObjCObjFieldGenerator::DetermineForwardDeclarations(fwd_decls,
54 include_external_types);
55 // Within a file there is no requirement on the order of the messages, so
56 // local references need a forward declaration. External files (not WKTs),
57 // need one when requested.
58 if ((include_external_types && !IsProtobufLibraryBundledProtoFile(
59 descriptor_->message_type()->file())) ||
60 descriptor_->file() == descriptor_->message_type()->file()) {
61 fwd_decls->insert(absl::StrCat("@class ", variable("msg_type"), ";"));
62 }
63 }
64
DetermineObjectiveCClassDefinitions(absl::btree_set<std::string> * fwd_decls) const65 void MessageFieldGenerator::DetermineObjectiveCClassDefinitions(
66 absl::btree_set<std::string>* fwd_decls) const {
67 fwd_decls->insert(ObjCClassDeclaration(variable("msg_type")));
68 }
69
DetermineNeededFiles(absl::flat_hash_set<const FileDescriptor * > * deps) const70 void MessageFieldGenerator::DetermineNeededFiles(
71 absl::flat_hash_set<const FileDescriptor*>* deps) const {
72 if (descriptor_->file() != descriptor_->message_type()->file()) {
73 deps->insert(descriptor_->message_type()->file());
74 }
75 }
76
RepeatedMessageFieldGenerator(const FieldDescriptor * descriptor,const GenerationOptions & generation_options)77 RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
78 const FieldDescriptor* descriptor,
79 const GenerationOptions& generation_options)
80 : RepeatedFieldGenerator(descriptor, generation_options) {
81 SetMessageVariables(descriptor, &variables_);
82 }
83
DetermineForwardDeclarations(absl::btree_set<std::string> * fwd_decls,bool include_external_types) const84 void RepeatedMessageFieldGenerator::DetermineForwardDeclarations(
85 absl::btree_set<std::string>* fwd_decls,
86 bool include_external_types) const {
87 RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls,
88 include_external_types);
89 // Within a file there is no requirement on the order of the messages, so
90 // local references need a forward declaration. External files (not WKTs),
91 // need one when requested.
92 if ((include_external_types && !IsProtobufLibraryBundledProtoFile(
93 descriptor_->message_type()->file())) ||
94 descriptor_->file() == descriptor_->message_type()->file()) {
95 fwd_decls->insert(absl::StrCat("@class ", variable("msg_type"), ";"));
96 }
97 }
98
DetermineObjectiveCClassDefinitions(absl::btree_set<std::string> * fwd_decls) const99 void RepeatedMessageFieldGenerator::DetermineObjectiveCClassDefinitions(
100 absl::btree_set<std::string>* fwd_decls) const {
101 fwd_decls->insert(ObjCClassDeclaration(variable("msg_type")));
102 }
103
DetermineNeededFiles(absl::flat_hash_set<const FileDescriptor * > * deps) const104 void RepeatedMessageFieldGenerator::DetermineNeededFiles(
105 absl::flat_hash_set<const FileDescriptor*>* deps) const {
106 if (descriptor_->file() != descriptor_->message_type()->file()) {
107 deps->insert(descriptor_->message_type()->file());
108 }
109 }
110
111 } // namespace objectivec
112 } // namespace compiler
113 } // namespace protobuf
114 } // namespace google
115