// Copyright 2019 The MediaPipe Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef MEDIAPIPE_FRAMEWORK_TOOL_TEMPLATE_PARSER_H_ #define MEDIAPIPE_FRAMEWORK_TOOL_TEMPLATE_PARSER_H_ #include #include #include #include #include "absl/base/macros.h" #include "mediapipe/framework/port/advanced_proto_inc.h" namespace mediapipe { namespace tool { class TemplateParser { public: // A data structure for reporting source code locations. class ParseInfoTree; // For parsing mediapipe templates, use this class. class Parser { public: Parser(); ~Parser(); // Like TextFormat::Parse(). bool Parse(proto_ns::io::ZeroCopyInputStream* input, proto_ns::Message* output); // Like TextFormat::ParseFromString(). bool ParseFromString(const std::string& input, proto_ns::Message* output); // Like TextFormat::Merge(). bool Merge(proto_ns::io::ZeroCopyInputStream* input, proto_ns::Message* output); // Like TextFormat::MergeFromString(). bool MergeFromString(const std::string& input, proto_ns::Message* output); // Set where to report parse errors. If NULL (the default), errors will // be printed to stderr. void RecordErrorsTo(proto_ns::io::ErrorCollector* error_collector) { error_collector_ = error_collector; } // Set how parser finds extensions. If NULL (the default), the // parser will use the standard Reflection object associated with // the message being parsed. void SetFinder(proto_ns::TextFormat::Finder* finder) { finder_ = finder; } // Sets where location information about the parse will be written. If NULL // (the default), then no location will be written. void WriteLocationsTo(ParseInfoTree* tree) { parse_info_tree_ = tree; } // Normally parsing fails if, after parsing, output->IsInitialized() // returns false. Call AllowPartialMessage(true) to skip this check. void AllowPartialMessage(bool allow) { allow_partial_ = allow; } // Allow field names to be matched case-insensitively. // This is not advisable if there are fields that only differ in case, or // if you want to enforce writing in the canonical form. // This is 'false' by default. void AllowCaseInsensitiveField(bool allow) { allow_case_insensitive_field_ = allow; } // Like TextFormat::ParseFieldValueFromString bool ParseFieldValueFromString(const std::string& input, const proto_ns::FieldDescriptor* field, proto_ns::Message* output); void AllowFieldNumber(bool allow) { allow_field_number_ = allow; } private: // A specialization of ParserImpl for parsing mediapipe template rules. class MediaPipeParserImpl; // The internal class used to parse proto text. class ParserImpl; // Like TextFormat::Merge(). The provided implementation is used // to do the parsing. bool MergeUsingImpl(proto_ns::io::ZeroCopyInputStream* input, proto_ns::Message* output, ParserImpl* parser_impl); proto_ns::io::ErrorCollector* error_collector_; proto_ns::TextFormat::Finder* finder_; ParseInfoTree* parse_info_tree_; bool allow_partial_; bool allow_case_insensitive_field_; bool allow_unknown_field_; bool allow_unknown_enum_; bool allow_field_number_; bool allow_relaxed_whitespace_; bool allow_singular_overwrites_; }; }; // Data structure which is populated with the locations of each field // value parsed from the text. // Forked from class TemplateParser::ParseInfoTree { public: typedef proto_ns::TextFormat::ParseLocation ParseLocation; typedef proto_ns::FieldDescriptor FieldDescriptor; ParseInfoTree(); ParseInfoTree(const ParseInfoTree&) = delete; ParseInfoTree& operator=(const ParseInfoTree&) = delete; ~ParseInfoTree(); // Returns the parse location for index-th value of the field in the parsed // text. If none exists, returns a location with line = -1. Index should be // -1 for not-repeated fields. ParseLocation GetLocation(const FieldDescriptor* field, int index) const; // Returns the parse info tree for the given field, which must be a message // type. The nested information tree is owned by the root tree and will be // deleted when it is deleted. ParseInfoTree* GetTreeForNested(const FieldDescriptor* field, int index) const; // Records the starting location of a single value for a field. void RecordLocation(const FieldDescriptor* field, ParseLocation location); // Create and records a nested tree for a nested message field. ParseInfoTree* CreateNested(const FieldDescriptor* field); // Return the proto path for the last index for a field. std::string GetLastPath(const FieldDescriptor* field); // Return the proto path for the current message. std::string GetPath(); private: // Defines the map from the index-th field descriptor to its parse location. typedef std::map> LocationMap; // Defines the map from the index-th field descriptor to the nested parse // info tree. typedef std::map>> NestedMap; LocationMap locations_; NestedMap nested_; std::string path_; }; } // namespace tool } // namespace mediapipe #endif // MEDIAPIPE_FRAMEWORK_TOOL_TEMPLATE_PARSER_H_