1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef ZIRCON_SYSTEM_HOST_FIDL_INCLUDE_FIDL_C_GENERATOR_H_
6 #define ZIRCON_SYSTEM_HOST_FIDL_INCLUDE_FIDL_C_GENERATOR_H_
7 
8 #include <sstream>
9 #include <string>
10 #include <vector>
11 
12 #include "flat_ast.h"
13 #include "string_view.h"
14 
15 namespace fidl {
16 
17 // Methods or functions named "Emit..." are the actual interface to
18 // the C output.
19 
20 // Methods named "Generate..." directly generate C output, to either
21 // the header or source file, via the "Emit" routines.
22 
23 // Methods named "Produce..." indirectly generate C output by calling
24 // the Generate methods, and should not call the "Emit" functions
25 // directly.
26 
27 class CGenerator {
28 public:
CGenerator(const flat::Library * library)29     explicit CGenerator(const flat::Library* library)
30         : library_(library) {}
31 
32     ~CGenerator() = default;
33 
34     std::ostringstream ProduceHeader();
35     std::ostringstream ProduceClient();
36     std::ostringstream ProduceServer();
37 
38     enum class Transport {
39         Channel,
40         SocketControl,
41     };
42 
43     struct Member {
44         flat::Type::Kind kind;
45         flat::Decl::Kind decl_kind;
46         std::string type;
47         std::string name;
48         // Name of the element type for sequential collections.
49         // For (multidimensional-) arrays, it names the inner-most type.
50         // For FIDL vector<T>, it names T.
51         std::string element_type;
52         std::vector<uint32_t> array_counts;
53         types::Nullability nullability;
54         // Bound on the element count for string and vector collection types.
55         // When there is no limit, its value is UINT32_MAX.
56         // Method parameters are pre-validated against this bound at the beginning of a FIDL call.
57         uint32_t max_num_elements;
58     };
59 
60     struct NamedMessage {
61         std::string c_name;
62         std::string coded_name;
63         const std::vector<flat::Struct::Member>& parameters;
64         const TypeShape& typeshape;
65     };
66 
67     struct NamedMethod {
68         uint32_t ordinal;
69         std::string ordinal_name;
70         std::string identifier;
71         std::string c_name;
72         std::unique_ptr<NamedMessage> request;
73         std::unique_ptr<NamedMessage> response;
74     };
75 
76 private:
77     struct NamedConst {
78         std::string name;
79         const flat::Const& const_info;
80     };
81 
82     struct NamedEnum {
83         std::string name;
84         const flat::Enum& enum_info;
85     };
86 
87     struct NamedInterface {
88         std::string c_name;
89         std::string discoverable_name;
90         Transport transport;
91         std::vector<NamedMethod> methods;
92     };
93 
94     struct NamedStruct {
95         std::string c_name;
96         std::string coded_name;
97         const flat::Struct& struct_info;
98     };
99 
100     struct NamedTable {
101         std::string c_name;
102         std::string coded_name;
103         const flat::Table& table_info;
104     };
105 
106     struct NamedUnion {
107         std::string name;
108         const flat::Union& union_info;
109     };
110 
111     enum class StructKind {
112         kMessage,
113         kNonmessage,
114     };
115 
116     void GeneratePrologues();
117     void GenerateEpilogues();
118 
119     void GenerateIntegerDefine(StringView name, types::PrimitiveSubtype subtype, StringView value);
120     void GenerateIntegerTypedef(types::PrimitiveSubtype subtype, StringView name);
121     void GeneratePrimitiveDefine(StringView name, types::PrimitiveSubtype subtype, StringView value);
122     void GenerateStringDefine(StringView name, StringView value);
123     void GenerateStructTypedef(StringView name);
124 
125     void GenerateStructDeclaration(StringView name, const std::vector<Member>& members, StructKind kind);
126     void GenerateTaggedUnionDeclaration(StringView name, const std::vector<Member>& members);
127 
128     std::map<const flat::Decl*, NamedConst>
129     NameConsts(const std::vector<std::unique_ptr<flat::Const>>& const_infos);
130     std::map<const flat::Decl*, NamedEnum>
131     NameEnums(const std::vector<std::unique_ptr<flat::Enum>>& enum_infos);
132     std::map<const flat::Decl*, NamedInterface>
133     NameInterfaces(const std::vector<std::unique_ptr<flat::Interface>>& interface_infos);
134     std::map<const flat::Decl*, NamedStruct>
135     NameStructs(const std::vector<std::unique_ptr<flat::Struct>>& struct_infos);
136     std::map<const flat::Decl*, NamedTable>
137     NameTables(const std::vector<std::unique_ptr<flat::Table>>& table_infos);
138     std::map<const flat::Decl*, NamedUnion>
139     NameUnions(const std::vector<std::unique_ptr<flat::Union>>& union_infos);
140 
141     void ProduceConstForwardDeclaration(const NamedConst& named_const);
142     void ProduceEnumForwardDeclaration(const NamedEnum& named_enum);
143     void ProduceInterfaceForwardDeclaration(const NamedInterface& named_interface);
144     void ProduceStructForwardDeclaration(const NamedStruct& named_struct);
145     void ProduceTableForwardDeclaration(const NamedTable& named_table);
146     void ProduceUnionForwardDeclaration(const NamedUnion& named_union);
147 
148     void ProduceInterfaceExternDeclaration(const NamedInterface& named_interface);
149 
150     void ProduceConstDeclaration(const NamedConst& named_const);
151     void ProduceMessageDeclaration(const NamedMessage& named_message);
152     void ProduceInterfaceDeclaration(const NamedInterface& named_interface);
153     void ProduceStructDeclaration(const NamedStruct& named_struct);
154     void ProduceTableDeclaration(const NamedStruct& named_struct);
155     void ProduceUnionDeclaration(const NamedUnion& named_union);
156 
157     void ProduceInterfaceClientDeclaration(const NamedInterface& named_interface);
158     void ProduceInterfaceClientImplementation(const NamedInterface& named_interface);
159 
160     void ProduceInterfaceServerDeclaration(const NamedInterface& named_interface);
161     void ProduceInterfaceServerImplementation(const NamedInterface& named_interface);
162 
163     const flat::Library* library_;
164     std::ostringstream file_;
165 };
166 
167 } // namespace fidl
168 
169 #endif // ZIRCON_SYSTEM_HOST_FIDL_INCLUDE_FIDL_C_GENERATOR_H_
170