~ubuntu-branches/ubuntu/wily/puppet/wily-proposed

« back to all changes in this revision

Viewing changes to lib/puppet/pops/model/model_meta.rb

  • Committer: Package Import Robot
  • Author(s): Stig Sandbeck Mathisen
  • Date: 2014-10-24 13:47:15 UTC
  • mfrom: (3.1.64 sid)
  • Revision ID: package-import@ubuntu.com-20141024134715-6ig54u0c4gar36ss
Tags: 3.7.2-1
* Imported upstream release 3.7.2
* Declare compliance with Debian Policy 3.9.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#
 
2
# The Puppet Pops Metamodel
 
3
#
 
4
# This module contains a formal description of the Puppet Pops (*P*uppet *OP*eration instruction*S*).
 
5
# It describes a Metamodel containing DSL instructions, a description of PuppetType and related
 
6
# classes needed to evaluate puppet logic.
 
7
# The metamodel resembles the existing AST model, but it is a semantic model of instructions and
 
8
# the types that they operate on rather than an Abstract Syntax Tree, although closely related.
 
9
#
 
10
# The metamodel is anemic (has no behavior) except basic datatype and type
 
11
# assertions and reference/containment assertions.
 
12
# The metamodel is also a generalized description of the Puppet DSL to enable the
 
13
# same metamodel to be used to express Puppet DSL models (instances) with different semantics as
 
14
# the language evolves.
 
15
#
 
16
# The metamodel is concretized by a validator for a particular version of
 
17
# the Puppet DSL language.
 
18
#
 
19
# This metamodel is expressed using RGen.
 
20
#
 
21
 
 
22
require 'rgen/metamodel_builder'
 
23
 
 
24
module Puppet::Pops::Model
 
25
  extend RGen::MetamodelBuilder::ModuleExtension
 
26
 
 
27
  # A base class for modeled objects that makes them Visitable, and Adaptable.
 
28
  #
 
29
  class PopsObject < RGen::MetamodelBuilder::MMBase
 
30
    abstract
 
31
  end
 
32
 
 
33
  # A Positioned object has an offset measured in an opaque unit (representing characters) from the start
 
34
  # of a source text (starting
 
35
  # from 0), and a length measured in the same opaque unit. The resolution of the opaque unit requires the
 
36
  # aid of a Locator instance that knows about the measure. This information is stored in the model's
 
37
  # root node - a Program.
 
38
  #
 
39
  # The offset and length are optional if the source of the model is not from parsed text.
 
40
  #
 
41
  class Positioned < PopsObject
 
42
    abstract
 
43
    has_attr 'offset', Integer
 
44
    has_attr 'length', Integer
 
45
  end
 
46
 
 
47
  # @abstract base class for expressions
 
48
  class Expression < Positioned
 
49
    abstract
 
50
  end
 
51
 
 
52
  # A Nop - the "no op" expression.
 
53
  # @note not really needed since the evaluator can evaluate nil with the meaning of NoOp
 
54
  # @todo deprecate? May be useful if there is the need to differentiate between nil and Nop when transforming model.
 
55
  #
 
56
  class Nop < Expression
 
57
  end
 
58
 
 
59
  # A binary expression is abstract and has a left and a right expression. The order of evaluation
 
60
  # and semantics are determined by the concrete subclass.
 
61
  #
 
62
  class BinaryExpression < Expression
 
63
    abstract
 
64
    #
 
65
    # @!attribute [rw] left_expr
 
66
    #   @return [Expression]
 
67
    contains_one_uni 'left_expr', Expression, :lowerBound => 1
 
68
    contains_one_uni 'right_expr', Expression, :lowerBound => 1
 
69
  end
 
70
 
 
71
  # An unary expression is abstract and contains one expression. The semantics are determined by
 
72
  # a concrete subclass.
 
73
  #
 
74
  class UnaryExpression < Expression
 
75
    abstract
 
76
    contains_one_uni 'expr', Expression, :lowerBound => 1
 
77
  end
 
78
 
 
79
  # A class that simply evaluates to the contained expression.
 
80
  # It is of value in order to preserve user entered parentheses in transformations, and
 
81
  # transformations from model to source.
 
82
  #
 
83
  class ParenthesizedExpression < UnaryExpression; end
 
84
 
 
85
  # A boolean not expression, reversing the truth of the unary expr.
 
86
  #
 
87
  class NotExpression < UnaryExpression; end
 
88
 
 
89
  # An arithmetic expression reversing the polarity of the numeric unary expr.
 
90
  #
 
91
  class UnaryMinusExpression < UnaryExpression; end
 
92
 
 
93
  # Unfolds an array (a.k.a 'splat')
 
94
  class UnfoldExpression < UnaryExpression; end
 
95
 
 
96
  OpAssignment = RGen::MetamodelBuilder::DataTypes::Enum.new(
 
97
    :literals => [:'=', :'+=', :'-='],
 
98
    :name => 'OpAssignment')
 
99
 
 
100
  # An assignment expression assigns a value to the lval() of the left_expr.
 
101
  #
 
102
  class AssignmentExpression < BinaryExpression
 
103
    has_attr 'operator', OpAssignment, :lowerBound => 1
 
104
  end
 
105
 
 
106
  OpArithmetic = RGen::MetamodelBuilder::DataTypes::Enum.new(
 
107
    :literals => [:'+', :'-', :'*', :'%', :'/', :'<<', :'>>' ],
 
108
    :name => 'OpArithmetic')
 
109
 
 
110
  # An arithmetic expression applies an arithmetic operator on left and right expressions.
 
111
  #
 
112
  class ArithmeticExpression < BinaryExpression
 
113
    has_attr 'operator', OpArithmetic, :lowerBound => 1
 
114
  end
 
115
 
 
116
  OpRelationship = RGen::MetamodelBuilder::DataTypes::Enum.new(
 
117
    :literals => [:'->', :'<-', :'~>', :'<~'],
 
118
    :name => 'OpRelationship')
 
119
 
 
120
  # A relationship expression associates the left and right expressions
 
121
  #
 
122
  class RelationshipExpression < BinaryExpression
 
123
    has_attr 'operator', OpRelationship, :lowerBound => 1
 
124
  end
 
125
 
 
126
  # A binary expression, that accesses the value denoted by right in left. i.e. typically
 
127
  # expressed concretely in a language as left[right].
 
128
  #
 
129
  class AccessExpression < Expression
 
130
    contains_one_uni 'left_expr', Expression, :lowerBound => 1
 
131
    contains_many_uni 'keys', Expression, :lowerBound => 1
 
132
  end
 
133
 
 
134
  OpComparison = RGen::MetamodelBuilder::DataTypes::Enum.new(
 
135
    :literals => [:'==', :'!=', :'<', :'>', :'<=', :'>=' ],
 
136
    :name => 'OpComparison')
 
137
 
 
138
  # A comparison expression compares left and right using a comparison operator.
 
139
  #
 
140
  class ComparisonExpression < BinaryExpression
 
141
    has_attr 'operator', OpComparison, :lowerBound => 1
 
142
  end
 
143
 
 
144
  OpMatch = RGen::MetamodelBuilder::DataTypes::Enum.new(
 
145
    :literals => [:'!~', :'=~'],
 
146
    :name => 'OpMatch')
 
147
 
 
148
  # A match expression matches left and right using a matching operator.
 
149
  #
 
150
  class MatchExpression < BinaryExpression
 
151
    has_attr 'operator', OpMatch, :lowerBound => 1
 
152
  end
 
153
 
 
154
  # An 'in' expression checks if left is 'in' right
 
155
  #
 
156
  class InExpression < BinaryExpression; end
 
157
 
 
158
  # A boolean expression applies a logical connective operator (and, or) to left and right expressions.
 
159
  #
 
160
  class BooleanExpression < BinaryExpression
 
161
    abstract
 
162
  end
 
163
 
 
164
  # An and expression applies the logical connective operator and to left and right expression
 
165
  # and does not evaluate the right expression if the left expression is false.
 
166
  #
 
167
  class AndExpression < BooleanExpression; end
 
168
 
 
169
  # An or expression applies the logical connective operator or to the left and right expression
 
170
  # and does not evaluate the right expression if the left expression is true
 
171
  #
 
172
  class OrExpression < BooleanExpression; end
 
173
 
 
174
  # A literal list / array containing 0:M expressions.
 
175
  #
 
176
  class LiteralList < Expression
 
177
    contains_many_uni 'values', Expression
 
178
  end
 
179
 
 
180
  # A Keyed entry has a key and a value expression. It is typically used as an entry in a Hash.
 
181
  #
 
182
  class KeyedEntry < Positioned
 
183
    contains_one_uni 'key', Expression, :lowerBound => 1
 
184
    contains_one_uni 'value', Expression, :lowerBound => 1
 
185
  end
 
186
 
 
187
  # A literal hash is a collection of KeyedEntry objects
 
188
  #
 
189
  class LiteralHash < Expression
 
190
    contains_many_uni 'entries', KeyedEntry
 
191
  end
 
192
 
 
193
  # A block contains a list of expressions
 
194
  #
 
195
  class BlockExpression < Expression
 
196
    contains_many_uni 'statements', Expression
 
197
  end
 
198
 
 
199
  # A case option entry in a CaseStatement
 
200
  #
 
201
  class CaseOption < Expression
 
202
    contains_many_uni 'values', Expression, :lowerBound => 1
 
203
    contains_one_uni 'then_expr', Expression, :lowerBound => 1
 
204
  end
 
205
 
 
206
  # A case expression has a test, a list of options (multi values => block map).
 
207
  # One CaseOption may contain a LiteralDefault as value. This option will be picked if nothing
 
208
  # else matched.
 
209
  #
 
210
  class CaseExpression < Expression
 
211
    contains_one_uni 'test', Expression, :lowerBound => 1
 
212
    contains_many_uni 'options', CaseOption
 
213
  end
 
214
 
 
215
  # A query expression is an expression that is applied to some collection.
 
216
  # The contained optional expression may contain different types of relational expressions depending
 
217
  # on what the query is applied to.
 
218
  #
 
219
  class QueryExpression < Expression
 
220
    abstract
 
221
    contains_one_uni 'expr', Expression, :lowerBound => 0
 
222
  end
 
223
 
 
224
  # An exported query is a special form of query that searches for exported objects.
 
225
  #
 
226
  class ExportedQuery < QueryExpression
 
227
  end
 
228
 
 
229
  # A virtual query is a special form of query that searches for virtual objects.
 
230
  #
 
231
  class VirtualQuery < QueryExpression
 
232
  end
 
233
 
 
234
  OpAttribute = RGen::MetamodelBuilder::DataTypes::Enum.new(
 
235
    :literals => [:'=>', :'+>', ],
 
236
    :name => 'OpAttribute')
 
237
 
 
238
  class AbstractAttributeOperation < Positioned
 
239
  end
 
240
 
 
241
  # An attribute operation sets or appends a value to a named attribute.
 
242
  #
 
243
  class AttributeOperation < AbstractAttributeOperation
 
244
    has_attr 'attribute_name', String, :lowerBound => 1
 
245
    has_attr 'operator', OpAttribute, :lowerBound => 1
 
246
    contains_one_uni 'value_expr', Expression, :lowerBound => 1
 
247
  end
 
248
 
 
249
  # An attribute operation containing an expression that must evaluate to a Hash
 
250
  #
 
251
  class AttributesOperation < AbstractAttributeOperation
 
252
    contains_one_uni 'expr', Expression, :lowerBound => 1
 
253
  end
 
254
 
 
255
  # An object that collects stored objects from the central cache and returns
 
256
  # them to the current host. Operations may optionally be applied.
 
257
  #
 
258
  class CollectExpression < Expression
 
259
    contains_one_uni 'type_expr', Expression, :lowerBound => 1
 
260
    contains_one_uni 'query', QueryExpression, :lowerBound => 1
 
261
    contains_many_uni 'operations', AttributeOperation
 
262
  end
 
263
 
 
264
  class Parameter < Positioned
 
265
    has_attr 'name', String, :lowerBound => 1
 
266
    contains_one_uni 'value', Expression
 
267
    contains_one_uni 'type_expr', Expression, :lowerBound => 0
 
268
    has_attr 'captures_rest', Boolean
 
269
  end
 
270
 
 
271
  # Abstract base class for definitions.
 
272
  #
 
273
  class Definition < Expression
 
274
    abstract
 
275
  end
 
276
 
 
277
  # Abstract base class for named and parameterized definitions.
 
278
  class NamedDefinition < Definition
 
279
    abstract
 
280
    has_attr 'name', String, :lowerBound => 1
 
281
    contains_many_uni 'parameters', Parameter
 
282
    contains_one_uni 'body', Expression
 
283
  end
 
284
 
 
285
  # A resource type definition (a 'define' in the DSL).
 
286
  #
 
287
  class ResourceTypeDefinition < NamedDefinition
 
288
  end
 
289
 
 
290
  # A node definition matches hosts using Strings, or Regular expressions. It may inherit from
 
291
  # a parent node (also using a String or Regular expression).
 
292
  #
 
293
  class NodeDefinition < Definition
 
294
    contains_one_uni 'parent', Expression
 
295
    contains_many_uni 'host_matches', Expression, :lowerBound => 1
 
296
    contains_one_uni 'body', Expression
 
297
  end
 
298
 
 
299
  class LocatableExpression < Expression
 
300
    has_many_attr 'line_offsets', Integer
 
301
    has_attr 'locator', Object, :lowerBound => 1, :transient => true
 
302
  end
 
303
 
 
304
  # Contains one expression which has offsets reported virtually (offset against the Program's
 
305
  # overall locator).
 
306
  #
 
307
  class SubLocatedExpression < Expression
 
308
    contains_one_uni 'expr', Expression, :lowerBound => 1
 
309
 
 
310
    # line offset index for contained expressions
 
311
    has_many_attr 'line_offsets', Integer
 
312
 
 
313
    # Number of preceding lines (before the line_offsets)
 
314
    has_attr 'leading_line_count', Integer
 
315
 
 
316
    # The offset of the leading source line (i.e. size of "left margin").
 
317
    has_attr 'leading_line_offset', Integer
 
318
 
 
319
    # The locator for the sub-locatable's children (not for the sublocator itself)
 
320
    # The locator is not serialized and is recreated on demand from the indexing information
 
321
    # in self.
 
322
    #
 
323
    has_attr 'locator', Object, :lowerBound => 1, :transient => true
 
324
  end
 
325
 
 
326
  # A heredoc is a wrapper around a LiteralString or a ConcatenatedStringExpression with a specification
 
327
  # of syntax. The expectation is that "syntax" has meaning to a validator. A syntax of nil or '' means
 
328
  # "unspecified syntax".
 
329
  #
 
330
  class HeredocExpression < Expression
 
331
    has_attr 'syntax', String
 
332
    contains_one_uni 'text_expr', Expression, :lowerBound => 1
 
333
  end
 
334
 
 
335
  # A class definition
 
336
  #
 
337
  class HostClassDefinition < NamedDefinition
 
338
    has_attr 'parent_class', String
 
339
  end
 
340
 
 
341
  # i.e {|parameters| body }
 
342
  class LambdaExpression < Expression
 
343
    contains_many_uni 'parameters', Parameter
 
344
    contains_one_uni 'body', Expression
 
345
  end
 
346
 
 
347
  # If expression. If test is true, the then_expr part should be evaluated, else the (optional)
 
348
  # else_expr. An 'elsif' is simply an else_expr = IfExpression, and 'else' is simply else == Block.
 
349
  # a 'then' is typically a Block.
 
350
  #
 
351
  class IfExpression < Expression
 
352
    contains_one_uni 'test', Expression, :lowerBound => 1
 
353
    contains_one_uni 'then_expr', Expression, :lowerBound => 1
 
354
    contains_one_uni 'else_expr', Expression
 
355
  end
 
356
 
 
357
  # An if expression with boolean reversed test.
 
358
  #
 
359
  class UnlessExpression < IfExpression
 
360
  end
 
361
 
 
362
  # An abstract call.
 
363
  #
 
364
  class CallExpression < Expression
 
365
    abstract
 
366
    # A bit of a crutch; functions are either procedures (void return) or has an rvalue
 
367
    # this flag tells the evaluator that it is a failure to call a function that is void/procedure
 
368
    # where a value is expected.
 
369
    #
 
370
    has_attr 'rval_required', Boolean, :defaultValueLiteral => "false"
 
371
    contains_one_uni 'functor_expr', Expression, :lowerBound => 1
 
372
    contains_many_uni 'arguments', Expression
 
373
    contains_one_uni 'lambda', Expression
 
374
  end
 
375
 
 
376
  # A function call where the functor_expr should evaluate to something callable.
 
377
  #
 
378
  class CallFunctionExpression < CallExpression; end
 
379
 
 
380
  # A function call where the given functor_expr should evaluate to the name
 
381
  # of a function.
 
382
  #
 
383
  class CallNamedFunctionExpression < CallExpression; end
 
384
 
 
385
  # A method/function call where the function expr is a NamedAccess and with support for
 
386
  # an optional lambda block
 
387
  #
 
388
  class CallMethodExpression < CallExpression
 
389
  end
 
390
 
 
391
  # Abstract base class for literals.
 
392
  #
 
393
  class Literal < Expression
 
394
    abstract
 
395
  end
 
396
 
 
397
  # A literal value is an abstract value holder. The type of the contained value is
 
398
  # determined by the concrete subclass.
 
399
  #
 
400
  class LiteralValue < Literal
 
401
    abstract
 
402
  end
 
403
 
 
404
  # A Regular Expression Literal.
 
405
  #
 
406
  class LiteralRegularExpression < LiteralValue
 
407
    has_attr 'value', Object, :lowerBound => 1, :transient => true
 
408
    has_attr 'pattern', String, :lowerBound => 1
 
409
  end
 
410
 
 
411
  # A Literal String
 
412
  #
 
413
  class LiteralString < LiteralValue
 
414
    has_attr 'value', String, :lowerBound => 1
 
415
  end
 
416
 
 
417
  class LiteralNumber < LiteralValue
 
418
    abstract
 
419
  end
 
420
 
 
421
  # A literal number has a radix of decimal (10), octal (8), or hex (16) to enable string conversion with the input radix.
 
422
  # By default, a radix of 10 is used.
 
423
  #
 
424
  class LiteralInteger < LiteralNumber
 
425
    has_attr 'radix', Integer, :lowerBound => 1, :defaultValueLiteral => "10"
 
426
    has_attr 'value', Integer, :lowerBound => 1
 
427
  end
 
428
 
 
429
  class LiteralFloat < LiteralNumber
 
430
    has_attr 'value', Float, :lowerBound => 1
 
431
  end
 
432
 
 
433
  # The DSL `undef`.
 
434
  #
 
435
  class LiteralUndef < Literal; end
 
436
 
 
437
  # The DSL `default`
 
438
  class LiteralDefault < Literal; end
 
439
 
 
440
  # DSL `true` or `false`
 
441
  class LiteralBoolean < LiteralValue
 
442
    has_attr 'value', Boolean, :lowerBound => 1
 
443
  end
 
444
 
 
445
  # A text expression is an interpolation of an expression. If the embedded expression is
 
446
  # a QualifiedName, it is taken as a variable name and resolved. All other expressions are evaluated.
 
447
  # The result is transformed to a string.
 
448
  #
 
449
  class TextExpression < UnaryExpression; end
 
450
 
 
451
  # An interpolated/concatenated string. The contained segments are expressions. Verbatim sections
 
452
  # should be LiteralString instances, and interpolated expressions should either be
 
453
  # TextExpression instances (if QualifiedNames should be turned into variables), or any other expression
 
454
  # if such treatment is not needed.
 
455
  #
 
456
  class ConcatenatedString < Expression
 
457
    contains_many_uni 'segments', Expression
 
458
  end
 
459
 
 
460
  # A DSL NAME (one or multiple parts separated by '::').
 
461
  #
 
462
  class QualifiedName < LiteralValue
 
463
    has_attr 'value', String, :lowerBound => 1
 
464
  end
 
465
 
 
466
  # Represents a parsed reserved word
 
467
  class ReservedWord < LiteralValue
 
468
    has_attr 'word', String, :lowerBound => 1
 
469
  end
 
470
 
 
471
  # A DSL CLASSREF (one or multiple parts separated by '::' where (at least) the first part starts with an upper case letter).
 
472
  #
 
473
  class QualifiedReference < LiteralValue
 
474
    has_attr 'value', String, :lowerBound => 1
 
475
  end
 
476
 
 
477
  # A Variable expression looks up value of expr (some kind of name) in scope.
 
478
  # The expression is typically a QualifiedName, or QualifiedReference.
 
479
  #
 
480
  class VariableExpression < UnaryExpression; end
 
481
 
 
482
  # Epp start
 
483
  class EppExpression < Expression
 
484
    # EPP can be specified without giving any parameter specification.
 
485
    # However, the parameters of the lambda in that case are the empty
 
486
    # array, which is the same as when the parameters are explicity
 
487
    # specified as empty. This attribute tracks that difference.
 
488
    has_attr 'parameters_specified', Boolean
 
489
    contains_one_uni 'body', Expression
 
490
  end
 
491
 
 
492
  # A string to render
 
493
  class RenderStringExpression < LiteralString
 
494
  end
 
495
 
 
496
  # An expression to evluate and render
 
497
  class RenderExpression < UnaryExpression
 
498
  end
 
499
 
 
500
  # A resource body describes one resource instance
 
501
  #
 
502
  class ResourceBody < Positioned
 
503
    contains_one_uni 'title', Expression
 
504
    contains_many_uni 'operations', AbstractAttributeOperation
 
505
  end
 
506
 
 
507
  ResourceFormEnum = RGen::MetamodelBuilder::DataTypes::Enum.new(
 
508
    :literals => [:regular, :virtual, :exported ],
 
509
    :name => 'ResourceFormEnum')
 
510
 
 
511
  # An abstract resource describes the form of the resource (regular, virtual or exported)
 
512
  # and adds convenience methods to ask if it is virtual or exported.
 
513
  # All derived classes may not support all forms, and these needs to be validated
 
514
  #
 
515
  class AbstractResource < Expression
 
516
    abstract
 
517
    has_attr 'form', ResourceFormEnum, :lowerBound => 1, :defaultValueLiteral => "regular"
 
518
    has_attr 'virtual', Boolean, :derived => true
 
519
    has_attr 'exported', Boolean, :derived => true
 
520
  end
 
521
 
 
522
  # A resource expression is used to instantiate one or many resource. Resources may optionally
 
523
  # be virtual or exported, an exported resource is always virtual.
 
524
  #
 
525
  class ResourceExpression < AbstractResource
 
526
    contains_one_uni 'type_name', Expression, :lowerBound => 1
 
527
    contains_many_uni 'bodies', ResourceBody
 
528
  end
 
529
 
 
530
  # A resource defaults sets defaults for a resource type. This class inherits from AbstractResource
 
531
  # but does only support the :regular form (this is intentional to be able to produce better error messages
 
532
  # when illegal forms are applied to a model.
 
533
  #
 
534
  class ResourceDefaultsExpression < AbstractResource
 
535
    contains_one_uni 'type_ref', Expression
 
536
    contains_many_uni 'operations', AbstractAttributeOperation
 
537
  end
 
538
 
 
539
  # A resource override overrides already set values.
 
540
  #
 
541
  class ResourceOverrideExpression < AbstractResource
 
542
    contains_one_uni 'resources', Expression, :lowerBound => 1
 
543
    contains_many_uni 'operations', AbstractAttributeOperation
 
544
  end
 
545
 
 
546
  # A selector entry describes a map from matching_expr to value_expr.
 
547
  #
 
548
  class SelectorEntry < Positioned
 
549
    contains_one_uni 'matching_expr', Expression, :lowerBound => 1
 
550
    contains_one_uni 'value_expr', Expression, :lowerBound => 1
 
551
  end
 
552
 
 
553
  # A selector expression represents a mapping from a left_expr to a matching SelectorEntry.
 
554
  #
 
555
  class SelectorExpression < Expression
 
556
    contains_one_uni 'left_expr', Expression, :lowerBound => 1
 
557
    contains_many_uni 'selectors', SelectorEntry
 
558
  end
 
559
 
 
560
  # A named access expression looks up a named part. (e.g. $a.b)
 
561
  #
 
562
  class NamedAccessExpression < BinaryExpression; end
 
563
 
 
564
  # A Program is the top level construct returned by the parser
 
565
  # it contains the parsed result in the body, and has a reference to the full source text,
 
566
  # and its origin. The line_offset's is an array with the start offset of each line.
 
567
  #
 
568
  class Program < PopsObject
 
569
    contains_one_uni 'body', Expression
 
570
    has_many 'definitions', Definition
 
571
    has_attr 'source_text', String
 
572
    has_attr 'source_ref', String
 
573
    has_many_attr 'line_offsets', Integer
 
574
    has_attr 'locator', Object, :lowerBound => 1, :transient => true
 
575
  end
 
576
end