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