1 // Copyright (c) 2013 The Chromium 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 TOOLS_GN_VALUE_H_ 6 #define TOOLS_GN_VALUE_H_ 7 8 #include <stdint.h> 9 10 #include <map> 11 #include <memory> 12 13 #include "base/logging.h" 14 #include "gn/err.h" 15 16 class ParseNode; 17 class Scope; 18 19 // Represents a variable value in the interpreter. 20 class Value { 21 public: 22 enum Type { 23 NONE = 0, 24 BOOLEAN, 25 INTEGER, 26 STRING, 27 LIST, 28 SCOPE, 29 }; 30 31 Value(); 32 Value(const ParseNode* origin, Type t); 33 Value(const ParseNode* origin, bool bool_val); 34 Value(const ParseNode* origin, int64_t int_val); 35 Value(const ParseNode* origin, std::string str_val); 36 Value(const ParseNode* origin, const char* str_val); 37 // Values "shouldn't" have null scopes when type == Scope, so be sure to 38 // always set one. However, this is not asserted since there are some 39 // use-cases for creating values and immediately setting the scope on it. So 40 // you can pass a null scope here if you promise to set it before any other 41 // code gets it (code will generally assume the scope is not null). 42 Value(const ParseNode* origin, std::unique_ptr<Scope> scope); 43 44 Value(const Value& other); 45 Value(Value&& other) noexcept; 46 ~Value(); 47 48 Value& operator=(const Value& other); 49 Value& operator=(Value&& other) noexcept; 50 type()51 Type type() const { return type_; } 52 53 // Returns a string describing the given type. 54 static const char* DescribeType(Type t); 55 56 // Returns the node that made this. May be NULL. origin()57 const ParseNode* origin() const { return origin_; } set_origin(const ParseNode * o)58 void set_origin(const ParseNode* o) { origin_ = o; } 59 boolean_value()60 bool& boolean_value() { 61 DCHECK(type_ == BOOLEAN); 62 return boolean_value_; 63 } boolean_value()64 const bool& boolean_value() const { 65 DCHECK(type_ == BOOLEAN); 66 return boolean_value_; 67 } 68 int_value()69 int64_t& int_value() { 70 DCHECK(type_ == INTEGER); 71 return int_value_; 72 } int_value()73 const int64_t& int_value() const { 74 DCHECK(type_ == INTEGER); 75 return int_value_; 76 } 77 string_value()78 std::string& string_value() { 79 DCHECK(type_ == STRING); 80 return string_value_; 81 } string_value()82 const std::string& string_value() const { 83 DCHECK(type_ == STRING); 84 return string_value_; 85 } 86 list_value()87 std::vector<Value>& list_value() { 88 DCHECK(type_ == LIST); 89 return list_value_; 90 } list_value()91 const std::vector<Value>& list_value() const { 92 DCHECK(type_ == LIST); 93 return list_value_; 94 } 95 scope_value()96 Scope* scope_value() { 97 DCHECK(type_ == SCOPE); 98 return scope_value_.get(); 99 } scope_value()100 const Scope* scope_value() const { 101 DCHECK(type_ == SCOPE); 102 return scope_value_.get(); 103 } 104 void SetScopeValue(std::unique_ptr<Scope> scope); 105 106 // Converts the given value to a string. Returns true if strings should be 107 // quoted or the ToString of a string should be the string itself. If the 108 // string is quoted, it will also enable escaping. 109 std::string ToString(bool quote_strings) const; 110 111 // Verifies that the value is of the given type. If it isn't, returns 112 // false and sets the error. 113 bool VerifyTypeIs(Type t, Err* err) const; 114 115 // Compares values. Only the "value" is compared, not the origin. Scope 116 // values check only the contents of the current scope, and do not go to 117 // parent scopes. 118 bool operator==(const Value& other) const; 119 bool operator!=(const Value& other) const; 120 121 private: 122 void Deallocate(); 123 124 Type type_ = NONE; 125 const ParseNode* origin_ = nullptr; 126 127 union { 128 bool boolean_value_; 129 int64_t int_value_; 130 std::string string_value_; 131 std::vector<Value> list_value_; 132 std::unique_ptr<Scope> scope_value_; 133 }; 134 }; 135 136 #endif // TOOLS_GN_VALUE_H_ 137