| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef TOOLS_FIDL_FIDLC_INCLUDE_FIDL_JSON_GENERATOR_H_ |
| #define TOOLS_FIDL_FIDLC_INCLUDE_FIDL_JSON_GENERATOR_H_ |
| |
| #include <zircon/assert.h> |
| |
| #include <memory> |
| #include <sstream> |
| #include <string> |
| #include <string_view> |
| #include <vector> |
| |
| #include "experimental_flags.h" |
| #include "flat/compiler.h" |
| #include "flat_ast.h" |
| #include "json_writer.h" |
| |
| namespace fidl { |
| |
| struct NameSpan { |
| explicit NameSpan(const SourceSpan& span) |
| : filename(span.source_file().filename()), length(span.data().length()) { |
| span.SourceLine(&position); |
| } |
| |
| // TODO(fxbug.dev/7920): We are incorrectly assuming that the provided name is not |
| // anonymous, and relying on callers to avoid derefencing a nullptr |
| // location. |
| explicit NameSpan(const flat::Name& name) : NameSpan(name.span().value()) { |
| ZX_ASSERT_MSG(name.span().has_value(), "NameSpan was passed an anonymous name"); |
| } |
| |
| const std::string filename; |
| SourceFile::Position position; |
| const size_t length; |
| }; |
| |
| // Methods or functions named "Emit..." are the actual interface to |
| // the JSON output. |
| |
| // Methods named "Generate..." directly generate JSON output via the |
| // "Emit" routines. |
| |
| // Methods named "Produce..." indirectly generate JSON output by calling |
| // the Generate methods, and should not call the "Emit" functions |
| // directly. |
| |
| // |JsonWriter| requires the derived type as a template parameter so it can |
| // match methods declared with parameter overrides in the derived class. |
| class JSONGenerator : public utils::JsonWriter<JSONGenerator> { |
| public: |
| // "using" is required for overridden methods, so the implementations in |
| // both the base class and in this derived class are visible when matching |
| // parameter types |
| using utils::JsonWriter<JSONGenerator>::Generate; |
| using utils::JsonWriter<JSONGenerator>::GenerateArray; |
| |
| explicit JSONGenerator(const flat::Compilation* compilation, ExperimentalFlags experimental_flags) |
| : JsonWriter(json_file_), |
| compilation_(compilation), |
| experimental_flags_(experimental_flags) {} |
| |
| ~JSONGenerator() = default; |
| |
| std::ostringstream Produce(); |
| |
| void Generate(SourceSpan value); |
| void Generate(NameSpan value); |
| |
| void Generate(types::HandleSubtype value); |
| void Generate(types::Nullability value); |
| void Generate(types::Strictness value); |
| void Generate(types::Openness value); |
| |
| void Generate(const raw::Identifier& value); |
| void Generate(const flat::AttributeArg& value); |
| void Generate(const flat::Attribute& value); |
| void Generate(const flat::AttributeList& value); |
| void Generate(const raw::Ordinal64& value); |
| |
| void Generate(const TypeShape& type_shape); |
| void Generate(const FieldShape& type_shape); |
| |
| void GenerateDeclName(const flat::Name& name); |
| void Generate(const flat::Name& value); |
| void Generate(const flat::Type* value); |
| void Generate(const flat::Constant& value); |
| void Generate(const flat::ConstantValue& value); |
| void Generate(const flat::Bits& value); |
| void Generate(const flat::Bits::Member& value); |
| void Generate(const flat::Const& value); |
| void Generate(const flat::Enum& value); |
| void Generate(const flat::Enum::Member& value); |
| void Generate(const flat::Protocol& value); |
| void Generate(const flat::Protocol::ComposedProtocol& composed_protocol); |
| void Generate(const flat::Protocol::MethodWithInfo& value); |
| void Generate(const flat::LiteralConstant& value); |
| void Generate(const flat::Resource& value); |
| void Generate(const flat::Resource::Property& value); |
| void Generate(const flat::Service& value); |
| void Generate(const flat::Service::Member& value); |
| void Generate(const flat::Struct& value); |
| void Generate(const flat::Struct::Member& value); |
| void Generate(const flat::Table& value); |
| void Generate(const flat::Table::Member& value); |
| void Generate(const flat::Union& value); |
| void Generate(const flat::Union::Member& value); |
| void Generate(const flat::LayoutInvocation& value); |
| void Generate(const flat::TypeConstructor& value); |
| void Generate(const flat::TypeAlias& value); |
| void Generate(const flat::Compilation::Dependency& dependency); |
| |
| private: |
| enum TypeKind { |
| kConcrete, |
| kParameterized, |
| kRequestPayload, |
| kResponsePayload, |
| }; |
| void GenerateTypeAndFromTypeAlias(TypeKind parent_type_kind, const flat::TypeConstructor* value, |
| Position position = Position::kSubsequent); |
| void GenerateTypeAndFromTypeAlias(const flat::TypeConstructor* value, |
| Position position = Position::kSubsequent); |
| |
| // This is a generator for the builtin generics: array, vector, and request. |
| // The "type" argument is the resolved type of the parameterized type to be |
| // generated, and the "type_ctor" argument is the de-aliased constructor for |
| // that type. For example, consider the following FIDL |
| // |
| // alias Foo = vector<bool>:5; |
| // |
| // struct Example { |
| // bar Foo?; |
| // }; |
| // |
| // When GenerateParameterizedType is called for Example.bar, the "type" will |
| // be a nullable vector of size 5, but the de-aliased constructor passed in |
| // will be the underlying type for just Foo, in this is case "vector<bool:5>." |
| void GenerateParameterizedType(TypeKind parent_type_kind, const flat::Type* type, |
| const flat::TypeConstructor* type_ctor, |
| Position position = Position::kSubsequent); |
| void GenerateExperimentalMaybeFromTypeAlias(const flat::LayoutInvocation& invocation); |
| void GenerateDeclarationsEntry(int count, const flat::Name& name, std::string_view decl_kind); |
| void GenerateDeclarationsMember(const flat::Compilation::Declarations& declarations, |
| Position position = Position::kSubsequent); |
| void GenerateExternalDeclarationsEntry(int count, const flat::Name& name, |
| std::string_view decl_kind, |
| std::optional<types::Resourceness> maybe_resourceness); |
| void GenerateExternalDeclarationsMember(const flat::Compilation::Declarations& declarations, |
| Position position = Position::kSubsequent); |
| void GenerateTypeShapes(const flat::Object& object); |
| void GenerateFieldShapes(const flat::Struct::Member& struct_member); |
| |
| template <typename T> |
| std::vector<std::reference_wrapper<const T>> FilterDecls( |
| const std::vector<std::unique_ptr<T>>& vector); |
| template <typename T> |
| std::vector<std::reference_wrapper<const T>> FilterDecls2(const std::vector<const T*>& vector); |
| |
| const flat::Compilation* compilation_; |
| const ExperimentalFlags experimental_flags_; |
| std::ostringstream json_file_; |
| }; |
| |
| } // namespace fidl |
| |
| #endif // TOOLS_FIDL_FIDLC_INCLUDE_FIDL_JSON_GENERATOR_H_ |