// Copyright (c) 2013 The Chromium 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_GN_VALUE_H_ #define TOOLS_GN_VALUE_H_ #include #include #include #include "base/logging.h" #include "base/macros.h" #include "tools/gn/err.h" class ParseNode; class Scope; // Represents a variable value in the interpreter. class Value { public: enum Type { NONE = 0, BOOLEAN, INTEGER, STRING, LIST, SCOPE, }; Value(); Value(const ParseNode* origin, Type t); Value(const ParseNode* origin, bool bool_val); Value(const ParseNode* origin, int64_t int_val); Value(const ParseNode* origin, std::string str_val); Value(const ParseNode* origin, const char* str_val); // Values "shouldn't" have null scopes when type == Scope, so be sure to // always set one. However, this is not asserted since there are some // use-cases for creating values and immediately setting the scope on it. So // you can pass a null scope here if you promise to set it before any other // code gets it (code will generally assume the scope is not null). Value(const ParseNode* origin, std::unique_ptr scope); Value(const Value& other); Value(Value&& other) noexcept; ~Value(); Value& operator=(const Value& other); Value& operator=(Value&& other) = default; Type type() const { return type_; } // Returns a string describing the given type. static const char* DescribeType(Type t); // Returns the node that made this. May be NULL. const ParseNode* origin() const { return origin_; } void set_origin(const ParseNode* o) { origin_ = o; } bool& boolean_value() { DCHECK(type_ == BOOLEAN); return boolean_value_; } const bool& boolean_value() const { DCHECK(type_ == BOOLEAN); return boolean_value_; } int64_t& int_value() { DCHECK(type_ == INTEGER); return int_value_; } const int64_t& int_value() const { DCHECK(type_ == INTEGER); return int_value_; } std::string& string_value() { DCHECK(type_ == STRING); return string_value_; } const std::string& string_value() const { DCHECK(type_ == STRING); return string_value_; } std::vector& list_value() { DCHECK(type_ == LIST); return list_value_; } const std::vector& list_value() const { DCHECK(type_ == LIST); return list_value_; } Scope* scope_value() { DCHECK(type_ == SCOPE); return scope_value_.get(); } const Scope* scope_value() const { DCHECK(type_ == SCOPE); return scope_value_.get(); } void SetScopeValue(std::unique_ptr scope); // Converts the given value to a string. Returns true if strings should be // quoted or the ToString of a string should be the string itself. If the // string is quoted, it will also enable escaping. std::string ToString(bool quote_strings) const; // Verifies that the value is of the given type. If it isn't, returns // false and sets the error. bool VerifyTypeIs(Type t, Err* err) const; // Compares values. Only the "value" is compared, not the origin. bool operator==(const Value& other) const; bool operator!=(const Value& other) const; private: // This are a lot of objects associated with every Value that need // initialization and tear down every time. It might be more efficient to // create a union of ManualConstructor objects (see small_map) and only // use the one we care about. Type type_; std::string string_value_; bool boolean_value_; int64_t int_value_; std::vector list_value_; std::unique_ptr scope_value_; const ParseNode* origin_; }; #endif // TOOLS_GN_VALUE_H_