blob: d13fef706cdeba82df90318281689afd55c4ac3e [file] [log] [blame]
// Copyright 2014 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <expat.h>
#include <map>
#include <string>
#include <vector>
#include <base/check.h>
#include <base/macros.h>
#include "chromeos-dbus-bindings/interface.h"
namespace chromeos_dbus_bindings {
class XmlInterfaceParser {
using XmlAttributeMap = std::map<std::string, std::string>;
XmlInterfaceParser() = default;
XmlInterfaceParser(const XmlInterfaceParser&) = delete;
XmlInterfaceParser& operator=(const XmlInterfaceParser&) = delete;
virtual ~XmlInterfaceParser() = default;
bool ParseXmlInterfaceFile(const std::string& contents,
const std::vector<std::string>& ignore_interfaces);
const std::vector<Interface>& interfaces() const { return interfaces_; }
friend class XmlInterfaceParserTest;
// XML tag names.
static const char kArgumentTag[];
static const char kInterfaceTag[];
static const char kMethodTag[];
static const char kNodeTag[];
static const char kSignalTag[];
static const char kPropertyTag[];
static const char kAnnotationTag[];
static const char kDocStringTag[];
// XML attribute names.
static const char kNameAttribute[];
static const char kTypeAttribute[];
static const char kDirectionAttribute[];
static const char kAccessAttribute[];
static const char kValueAttribute[];
// XML argument directions.
static const char kArgumentDirectionIn[];
static const char kArgumentDirectionOut[];
// XML annotations.
static const char kTrue[];
static const char kFalse[];
static const char kMethodConst[];
static const char kMethodAsync[];
static const char kMethodIncludeDBusMessage[];
static const char kMethodKind[];
static const char kMethodKindSimple[];
static const char kMethodKindNormal[];
static const char kMethodKindAsync[];
static const char kMethodKindRaw[];
static const char kArgumentProtobufClass[];
// Element callbacks on |this| called by HandleElementStart() and
// HandleElementEnd(), respectively.
void OnOpenElement(const std::string& element_name,
const XmlAttributeMap& attributes);
void OnCloseElement(const std::string& element_name);
void OnCharData(const std::string& content);
// Methods for appending individual argument elements to the parser.
void AddMethodArgument(const XmlAttributeMap& attributes);
void AddSignalArgument(const XmlAttributeMap& attributes);
// Finds the |element_key| element in |attributes|. Returns true and sets
// |element_value| on success. Returns false otherwise.
static bool GetElementAttribute(const XmlAttributeMap& attributes,
const std::vector<std::string>& element_path,
const std::string& element_key,
std::string* element_value);
// Asserts that a non-empty |element_key| attribute appears in |attributes|.
// Returns the name on success, triggers a CHECK() otherwise.
static std::string GetValidatedElementAttribute(
const XmlAttributeMap& attributes,
const std::vector<std::string>& element_path,
const std::string& element_key);
// Calls GetValidatedElementAttribute() for the "name" property.
static std::string GetValidatedElementName(
const XmlAttributeMap& attributes,
const std::vector<std::string>& element_path);
// Method for extracting signal/method tag attributes to a struct.
static Interface::Argument ParseArgument(
const XmlAttributeMap& attributes,
const std::vector<std::string>& element_path);
// Method for extracting property tag attributes to a struct.
static Interface::Property ParseProperty(
const XmlAttributeMap& attributes,
const std::vector<std::string>& element_path);
// Expat element callback functions.
static void HandleElementStart(void* user_data,
const XML_Char* element,
const XML_Char** attr);
static void HandleElementEnd(void* user_data, const XML_Char* element);
static void HandleCharData(void* user_data, const char* content, int length);
// The output of the parse.
std::vector<Interface> interfaces_;
// A stack of <node> names used to track the object paths for interfaces.
std::vector<std::string> node_names_;
// Tracks where in the element traversal our parse has taken us.
std::vector<std::string> element_path_;
// Tracks the last argument that we've seen.
Interface::Argument* last_arg_;
} // namespace chromeos_dbus_bindings