summaryrefslogtreecommitdiffstats
path: root/tools/gn/value.h
blob: 44fba4adb2af16a450eda4608a767ed178a2bb1e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// 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 <stdint.h>
#include <map>

#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.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, scoped_ptr<Scope> scope);

  Value(const Value& other);
  ~Value();

  Value& operator=(const Value& other);

  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<Value>& list_value() {
    DCHECK(type_ == LIST);
    return list_value_;
  }
  const std::vector<Value>& 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(scoped_ptr<Scope> 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 SmallMap) and only
  // use the one we care about.
  Type type_;
  std::string string_value_;
  bool boolean_value_;
  int64_t int_value_;
  std::vector<Value> list_value_;
  scoped_ptr<Scope> scope_value_;

  const ParseNode* origin_;
};

#endif  // TOOLS_GN_VALUE_H_