parameters: (self,
                name,
                tag_id,
                parent,
                fields,
                is_abstract=False,
                extra_defs='',
                emit_default_constructor=True,
                use_custom_debug_string=False,
                comment=None)
docstring: Add a node class to be generated.
  
      Args:
        name: class name for this node
        tag_id: unique tag number for the node as a proto field or an enum value.
            tag_id for each node type is hard coded and should never change.
            Next tag_id: 202
        parent: class name of the parent node
        fields: list of fields in this class; created with Field function
        is_abstract: true if this node is an abstract class
        extra_defs: extra c++ definitions to put in this class.
        emit_default_constructor: If True, emit default constructor for this class
        use_custom_debug_string: If True, use hand-written
            CollectDebugStringFields and GetNameForDebugString c++ methods for
            DebugString.
        comment: Comment text for this node.  Text will be stripped and
            de-indented.
docstring_summary: Add a node class to be generated.
docstring_tokens: Add a node class to be generated .
function: def AddNode(self,
                name,
                tag_id,
                parent,
                fields,
                is_abstract=False,
                extra_defs='',
                emit_default_constructor=True,
                use_custom_debug_string=False,
                comment=None):
      """Add a node class to be generated.
  
      Args:
        name: class name for this node
        tag_id: unique tag number for the node as a proto field or an enum value.
            tag_id for each node type is hard coded and should never change.
            Next tag_id: 202
        parent: class name of the parent node
        fields: list of fields in this class; created with Field function
        is_abstract: true if this node is an abstract class
        extra_defs: extra c++ definitions to put in this class.
        emit_default_constructor: If True, emit default constructor for this class
        use_custom_debug_string: If True, use hand-written
            CollectDebugStringFields and GetNameForDebugString c++ methods for
            DebugString.
        comment: Comment text for this node.  Text will be stripped and
            de-indented.
      """
      assert name not in self.node_map, name
      assert name != ROOT_NODE_NAME, name
      assert parent in self.node_map or parent == ROOT_NODE_NAME, parent
      if parent == ROOT_NODE_NAME:
        # Nodes generally fit into these four top-level categories.
        # Nodes that are part of other nodes are usually ResolvedArguments.
        assert name in ('ResolvedArgument', 'ResolvedExpr', 'ResolvedScan',
                        'ResolvedStatement'), name
      assert len(fields) <= 32, 'More than 32 fields not supported'
      fields = [field.copy() for field in fields]
      extra_enum_decls, extra_enum_defs = self._ResolveImportEnums(name)
  
      make_enum_name_re = re.compile(r'([a-z])([A-Z])')
  
      def NameToEnumName(name):
        """Convert a camel-case c++ ClassName into CLASS_NAME."""
        return make_enum_name_re.sub(r'\1_\2', name).upper()
  
      # Add position-related field members.
      for (pos, field) in enumerate(fields):
        field.update({'bitmap': '(1<<%d)' % pos})
  
      # Compute list of fields inherited from the parent node.
      # Used for constructors that accept and pass on all inherited fields.
      inherited_fields = []
      if parent != ROOT_NODE_NAME:
        inherited_fields = (self.node_map[parent]['inherited_fields'] +
                            self.node_map[parent]['fields'])
  
      proto_type = '%sProto' % name
  
      # Marking classes and virtual methods as final may allow the
      # compiler to avoid some virtual function calls.
      if is_abstract:
        class_final = ''
        override_or_final = 'override'
        proto_field_type = 'Any%sProto' % name
      else:
        class_final = 'final'
        override_or_final = 'final'
        proto_field_type = proto_type
  
      has_node_vector_constructor_arg = any(
          field['is_node_vector'] and field['is_constructor_arg']
          for field in fields + inherited_fields)
  
      def JoinSections(a, b):
        separator = ''
        if a and b:
          separator = '\n'
        return a + separator + b
  
      node_dict = ({
          'name': name,
          'proto_type': proto_type,
          'proto_field_type': proto_field_type,
          'enum_name': NameToEnumName(name),
          'member_name': NameToEnumName(name).lower(),
          'node_kind_name': NameToNodeKindName(name, NODE_NAME_PREFIX),
          'tag_id': tag_id,
          'parent': parent,
          'parent_proto_container_type': 'Any%sProto' % parent,
          'parent_proto_type': '%sProto' % parent,
          'depth': (self.node_map[parent]['depth'] + 1
                    if parent != ROOT_NODE_NAME else 1),
          'is_abstract': is_abstract,
          'class_final': class_final,
          'override_or_final': override_or_final,
          'comment': CleanIndent(comment, prefix='// '),
          'javadoc': JavaDoc(comment, indent=2),
          'fields': fields,
          'inherited_fields': inherited_fields,
          'extra_enum_defs': extra_enum_defs,
          'extra_defs': JoinSections(extra_enum_decls,
                                     CleanIndent(extra_defs, '  ')),
          'emit_default_constructor': emit_default_constructor,
          'has_node_vector_constructor_arg': has_node_vector_constructor_arg,
          'use_custom_debug_string': use_custom_debug_string,
          'subclasses': []
      })
      # This is the name of the defining node rather than a reference to
      # avoid creating a recursive data structure that cannot be compared.
      # TraverseToRoot contains such a comparison.
      #
      # In the template, use the defining_node(field) function to find
      # the node in which this field is defined.
      for field in fields:
        field.update({'defining_node_name': name})
  
      self.nodes.append(node_dict)
      self.node_map[name] = node_dict
function_tokens: def AddNode ( self , name , tag_id , parent , fields , is_abstract = False , extra_defs = '' , emit_default_constructor = True , use_custom_debug_string = False , comment = None ) : assert name not in self . node_map , name assert name != ROOT_NODE_NAME , name assert parent in self . node_map or parent == ROOT_NODE_NAME , parent if parent == ROOT_NODE_NAME : # Nodes generally fit into these four top-level categories. # Nodes that are part of other nodes are usually ResolvedArguments. assert name in ( 'ResolvedArgument' , 'ResolvedExpr' , 'ResolvedScan' , 'ResolvedStatement' ) , name assert len ( fields ) <= 32 , 'More than 32 fields not supported' fields = [ field . copy ( ) for field in fields ] extra_enum_decls , extra_enum_defs = self . _ResolveImportEnums ( name ) make_enum_name_re = re . compile ( r'([a-z])([A-Z])' ) def NameToEnumName ( name ) : """Convert a camel-case c++ ClassName into CLASS_NAME.""" return make_enum_name_re . sub ( r'\1_\2' , name ) . upper ( ) # Add position-related field members. for ( pos , field ) in enumerate ( fields ) : field . update ( { 'bitmap' : '(1<<%d)' % pos } ) # Compute list of fields inherited from the parent node. # Used for constructors that accept and pass on all inherited fields. inherited_fields = [ ] if parent != ROOT_NODE_NAME : inherited_fields = ( self . node_map [ parent ] [ 'inherited_fields' ] + self . node_map [ parent ] [ 'fields' ] ) proto_type = '%sProto' % name # Marking classes and virtual methods as final may allow the # compiler to avoid some virtual function calls. if is_abstract : class_final = '' override_or_final = 'override' proto_field_type = 'Any%sProto' % name else : class_final = 'final' override_or_final = 'final' proto_field_type = proto_type has_node_vector_constructor_arg = any ( field [ 'is_node_vector' ] and field [ 'is_constructor_arg' ] for field in fields + inherited_fields ) def JoinSections ( a , b ) : separator = '' if a and b : separator = '\n' return a + separator + b node_dict = ( { 'name' : name , 'proto_type' : proto_type , 'proto_field_type' : proto_field_type , 'enum_name' : NameToEnumName ( name ) , 'member_name' : NameToEnumName ( name ) . lower ( ) , 'node_kind_name' : NameToNodeKindName ( name , NODE_NAME_PREFIX ) , 'tag_id' : tag_id , 'parent' : parent , 'parent_proto_container_type' : 'Any%sProto' % parent , 'parent_proto_type' : '%sProto' % parent , 'depth' : ( self . node_map [ parent ] [ 'depth' ] + 1 if parent != ROOT_NODE_NAME else 1 ) , 'is_abstract' : is_abstract , 'class_final' : class_final , 'override_or_final' : override_or_final , 'comment' : CleanIndent ( comment , prefix = '// ' ) , 'javadoc' : JavaDoc ( comment , indent = 2 ) , 'fields' : fields , 'inherited_fields' : inherited_fields , 'extra_enum_defs' : extra_enum_defs , 'extra_defs' : JoinSections ( extra_enum_decls , CleanIndent ( extra_defs , '  ' ) ) , 'emit_default_constructor' : emit_default_constructor , 'has_node_vector_constructor_arg' : has_node_vector_constructor_arg , 'use_custom_debug_string' : use_custom_debug_string , 'subclasses' : [ ] } ) # This is the name of the defining node rather than a reference to # avoid creating a recursive data structure that cannot be compared. # TraverseToRoot contains such a comparison. # # In the template, use the defining_node(field) function to find # the node in which this field is defined. for field in fields : field . update ( { 'defining_node_name' : name } ) self . nodes . append ( node_dict ) self . node_map [ name ] = node_dict