Add default values to dawn.json for dawncpp.h

This adds almost all default values in descriptors that are present in
WebGPU to the C++ interface for Dawn.

This also fixes the indentation of dawncpp.h both by reindenting the
template, and making the indentation counting in generator_lib.py more
precise.

BUG=dawn:22

Change-Id: I9a852d26f78a3349f3d6eee7237407d1cf8ca426
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/8680
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
diff --git a/dawn.json b/dawn.json
index 34b5700..cfb0db3 100644
--- a/dawn.json
+++ b/dawn.json
@@ -31,7 +31,7 @@
         "members": [
             {"name": "binding", "type": "uint32_t"},
             {"name": "buffer", "type": "buffer", "optional": true},
-            {"name": "offset", "type": "uint64_t"},
+            {"name": "offset", "type": "uint64_t", "default": "0"},
             {"name": "size", "type": "uint64_t"},
             {"name": "sampler", "type": "sampler", "optional": true},
             {"name": "texture view", "type": "texture view", "optional": true}
@@ -81,9 +81,9 @@
         "category": "structure",
         "extensible": false,
         "members": [
-            {"name": "operation", "type": "blend operation"},
-            {"name": "src factor", "type": "blend factor"},
-            {"name": "dst factor", "type": "blend factor"}
+            {"name": "operation", "type": "blend operation", "default": "add"},
+            {"name": "src factor", "type": "blend factor", "default": "one"},
+            {"name": "dst factor", "type": "blend factor", "default": "zero"}
         ]
     },
     "blend factor": {
@@ -121,7 +121,7 @@
             {"name": "format", "type": "texture format"},
             {"name": "alpha blend", "type": "blend descriptor"},
             {"name": "color blend", "type": "blend descriptor"},
-            {"name": "write mask", "type": "color write mask"}
+            {"name": "write mask", "type": "color write mask", "default": "all"}
         ]
     },
     "bool": {
@@ -168,7 +168,7 @@
         "extensible": true,
         "members": [
             {"name": "buffer", "type": "buffer"},
-            {"name": "offset", "type": "uint64_t"},
+            {"name": "offset", "type": "uint64_t", "default": 0},
             {"name": "row pitch", "type": "uint32_t"},
             {"name": "image height", "type": "uint32_t"}
         ]
@@ -353,8 +353,8 @@
                 "name": "dispatch",
                 "args": [
                     {"name": "x", "type": "uint32_t"},
-                    {"name": "y", "type": "uint32_t"},
-                    {"name": "z", "type": "uint32_t"}
+                    {"name": "y", "type": "uint32_t", "default": "1"},
+                    {"name": "z", "type": "uint32_t", "default": "1"}
                 ]
             },
             {
@@ -502,12 +502,12 @@
         "extensible": true,
         "members": [
             {"name": "format", "type": "texture format"},
-            {"name": "depth write enabled", "type": "bool"},
-            {"name": "depth compare", "type": "compare function"},
+            {"name": "depth write enabled", "type": "bool", "default": "false"},
+            {"name": "depth compare", "type": "compare function", "default": "always"},
             {"name": "stencil front", "type": "stencil state face descriptor"},
             {"name": "stencil back", "type": "stencil state face descriptor"},
-            {"name": "stencil read mask", "type": "uint32_t"},
-            {"name": "stencil write mask", "type": "uint32_t"}
+            {"name": "stencil read mask", "type": "uint32_t", "default": "0xFFFFFFFF"},
+            {"name": "stencil write mask", "type": "uint32_t", "default": "0xFFFFFFFF"}
         ]
     },
     "device error callback": {
@@ -563,7 +563,7 @@
         "category": "structure",
         "extensible": true,
         "members": [
-            {"name": "initial value", "type": "uint64_t"}
+            {"name": "initial value", "type": "uint64_t", "default": "0"}
         ]
     },
     "filter mode": {
@@ -595,7 +595,7 @@
         "extensible": false,
         "members": [
             {"name": "shader location", "type": "uint32_t"},
-            {"name": "offset", "type": "uint64_t"},
+            {"name": "offset", "type": "uint64_t", "default": "0"},
             {"name": "format", "type": "vertex format"}
         ]
     },
@@ -604,7 +604,7 @@
         "extensible": false,
         "members": [
             {"name": "stride", "type": "uint64_t"},
-            {"name": "step mode", "type": "input step mode"},
+            {"name": "step mode", "type": "input step mode", "default": "vertex"},
             {"name": "attribute count", "type": "uint32_t"},
             {"name": "attributes", "type": "vertex attribute descriptor", "annotation": "const*", "length": "attribute count"}
         ]
@@ -613,7 +613,7 @@
         "category": "structure",
         "extensible": true,
         "members": [
-            {"name": "index format", "type": "index format"},
+            {"name": "index format", "type": "index format", "default": "uint32"},
             {"name": "buffer count", "type": "uint32_t"},
             {"name": "buffers", "type": "vertex buffer descriptor", "annotation": "const*", "length": "buffer count"}
         ]
@@ -641,9 +641,9 @@
     "origin 3D": {
         "category": "structure",
         "members": [
-            {"name": "x", "type": "uint32_t"},
-            {"name": "y", "type": "uint32_t"},
-            {"name": "z", "type": "uint32_t"}
+            {"name": "x", "type": "uint32_t", "default": "0"},
+            {"name": "y", "type": "uint32_t", "default": "0"},
+            {"name": "z", "type": "uint32_t", "default": "0"}
         ]
     },
     "pipeline layout": {
@@ -706,11 +706,11 @@
         "category": "structure",
         "extensible": true,
         "members": [
-            {"name": "front face", "type": "front face"},
-            {"name": "cull mode", "type": "cull mode"},
-            {"name": "depth bias", "type": "int32_t"},
-            {"name": "depth bias slope scale", "type": "float"},
-            {"name": "depth bias clamp", "type": "float"}
+            {"name": "front face", "type": "front face", "default": "CCW"},
+            {"name": "cull mode", "type": "cull mode", "default": "none"},
+            {"name": "depth bias", "type": "int32_t", "default": "0"},
+            {"name": "depth bias slope scale", "type": "float", "default": "0.0f"},
+            {"name": "depth bias clamp", "type": "float", "default": "0.0f"}
         ]
     },
 
@@ -734,7 +734,7 @@
             {"name": "clear depth", "type": "float"},
             {"name": "stencil load op", "type": "load op"},
             {"name": "stencil store op", "type": "store op"},
-            {"name": "clear stencil", "type": "uint32_t"}
+            {"name": "clear stencil", "type": "uint32_t", "default": "0"}
         ]
     },
 
@@ -880,7 +880,7 @@
             {"name": "vertex input", "type": "vertex input descriptor", "annotation": "const*"},
             {"name": "primitive topology", "type": "primitive topology"},
             {"name": "rasterization state", "type": "rasterization state descriptor", "annotation": "const*"},
-            {"name": "sample count", "type": "uint32_t"},
+            {"name": "sample count", "type": "uint32_t", "default": "1"},
             {"name": "depth stencil state", "type": "depth stencil state descriptor", "annotation": "const*", "optional": true},
             {"name": "color state count", "type": "uint32_t"},
             {"name": "color states", "type": "color state descriptor", "annotation": "const*const*", "length": "color state count"}
@@ -893,15 +893,15 @@
         "category": "structure",
         "extensible": true,
         "members": [
-            {"name": "address mode u", "type": "address mode"},
-            {"name": "address mode v", "type": "address mode"},
-            {"name": "address mode w", "type": "address mode"},
-            {"name": "mag filter", "type": "filter mode"},
-            {"name": "min filter", "type": "filter mode"},
-            {"name": "mipmap filter", "type": "filter mode"},
-            {"name": "lod min clamp", "type": "float"},
-            {"name": "lod max clamp", "type": "float"},
-            {"name": "compare", "type": "compare function"}
+            {"name": "address mode u", "type": "address mode", "default": "clamp to edge"},
+            {"name": "address mode v", "type": "address mode", "default": "clamp to edge"},
+            {"name": "address mode w", "type": "address mode", "default": "clamp to edge"},
+            {"name": "mag filter", "type": "filter mode", "default": "nearest"},
+            {"name": "min filter", "type": "filter mode", "default": "nearest"},
+            {"name": "mipmap filter", "type": "filter mode", "default": "nearest"},
+            {"name": "lod min clamp", "type": "float", "default": "0.0f"},
+            {"name": "lod max clamp", "type": "float", "default": "1000.0f"},
+            {"name": "compare", "type": "compare function", "default": "never"}
         ]
     },
     "shader module": {
@@ -949,10 +949,10 @@
         "category": "structure",
         "extensible": false,
         "members": [
-            {"name": "compare", "type": "compare function"},
-            {"name": "fail op", "type": "stencil operation"},
-            {"name": "depth fail op", "type": "stencil operation"},
-            {"name": "pass op", "type": "stencil operation"}
+            {"name": "compare", "type": "compare function", "default": "always"},
+            {"name": "fail op", "type": "stencil operation", "default": "keep"},
+            {"name": "depth fail op", "type": "stencil operation", "default": "keep"},
+            {"name": "pass op", "type": "stencil operation", "default": "keep"}
         ]
     },
     "swap chain": {
@@ -1018,8 +1018,8 @@
         "extensible": true,
         "members": [
             {"name": "texture", "type": "texture"},
-            {"name": "mip level", "type": "uint32_t"},
-            {"name": "array layer", "type": "uint32_t"},
+            {"name": "mip level", "type": "uint32_t", "default": "0"},
+            {"name": "array layer", "type": "uint32_t", "default": "0"},
             {"name": "origin", "type": "origin 3D"}
         ]
     },
@@ -1028,12 +1028,12 @@
         "extensible": true,
         "members": [
             {"name": "usage", "type": "texture usage bit"},
-            {"name": "dimension", "type": "texture dimension"},
+            {"name": "dimension", "type": "texture dimension", "default": "2D"},
             {"name": "size", "type": "extent 3D"},
-            {"name": "array layer count", "type": "uint32_t"},
+            {"name": "array layer count", "type": "uint32_t", "default": "1"},
             {"name": "format", "type": "texture format"},
-            {"name": "mip level count", "type": "uint32_t"},
-            {"name": "sample count", "type": "uint32_t"}
+            {"name": "mip level count", "type": "uint32_t", "default": 1},
+            {"name": "sample count", "type": "uint32_t", "default": 1}
         ]
     },
     "texture dimension": {
@@ -1132,10 +1132,10 @@
         "members": [
             {"name": "format", "type": "texture format"},
             {"name": "dimension", "type": "texture view dimension"},
-            {"name": "base mip level", "type": "uint32_t"},
-            {"name": "mip level count", "type": "uint32_t"},
-            {"name": "base array layer", "type": "uint32_t"},
-            {"name": "array layer count", "type": "uint32_t"}
+            {"name": "base mip level", "type": "uint32_t", "default": "0"},
+            {"name": "mip level count", "type": "uint32_t", "default": "1"},
+            {"name": "base array layer", "type": "uint32_t", "default": "0"},
+            {"name": "array layer count", "type": "uint32_t", "default": "1"}
         ],
         "TODO": [
             "jiawei.shao@intel.com: Allow choosing the aspect (depth vs. stencil)"
diff --git a/generator/dawn_json_generator.py b/generator/dawn_json_generator.py
index 02dccfb..8b78796 100644
--- a/generator/dawn_json_generator.py
+++ b/generator/dawn_json_generator.py
@@ -94,7 +94,8 @@
 # Methods and structures are both "records", so record members correspond to
 # method arguments or structure members.
 class RecordMember:
-    def __init__(self, name, typ, annotation, optional, is_return_value):
+    def __init__(self, name, typ, annotation, optional=False,
+                 is_return_value=False, default_value=None):
         self.name = name
         self.type = typ
         self.annotation = annotation
@@ -102,6 +103,7 @@
         self.optional = optional
         self.is_return_value = is_return_value
         self.handle_type = None
+        self.default_value = default_value
 
     def set_handle_type(self, handle_type):
         assert self.type.dict_name == "ObjectHandle"
@@ -150,8 +152,10 @@
     members_by_name = {}
     for m in json_data:
         member = RecordMember(Name(m['name']), types[m['type']],
-                              m.get('annotation', 'value'), m.get('optional', False),
-                              m.get('is_return_value', False))
+                              m.get('annotation', 'value'),
+                              optional=m.get('optional', False),
+                              is_return_value=m.get('is_return_value', False),
+                              default_value=m.get('default', None))
         handle_type = m.get('handle_type')
         if handle_type:
             member.set_handle_type(types[handle_type])
@@ -299,12 +303,12 @@
                 continue
 
             # Create object method commands by prepending "self"
-            members = [RecordMember(Name('self'), types[api_object.dict_name], 'value', False, False)]
+            members = [RecordMember(Name('self'), types[api_object.dict_name], 'value')]
             members += method.arguments
 
             # Client->Server commands that return an object return the result object handle
             if method.return_type.category == 'object':
-                result = RecordMember(Name('result'), types['ObjectHandle'], 'value', False, True)
+                result = RecordMember(Name('result'), types['ObjectHandle'], 'value', is_return_value=True)
                 result.set_handle_type(method.return_type)
                 members.append(result)
 
diff --git a/generator/generator_lib.py b/generator/generator_lib.py
index fc355a9..01c8b91 100644
--- a/generator/generator_lib.py
+++ b/generator/generator_lib.py
@@ -103,8 +103,8 @@
             source = self.preprocess(f.read())
         return source, path, lambda: mtime == os.path.getmtime(path)
 
-    blockstart = re.compile('{%-?\s*(if|for|block)[^}]*%}')
-    blockend = re.compile('{%-?\s*end(if|for|block)[^}]*%}')
+    blockstart = re.compile('{%-?\s*(if|elif|else|for|block|macro)[^}]*%}')
+    blockend = re.compile('{%-?\s*(end(if|for|block|macro)|elif|else)[^}]*%}')
 
     def preprocess(self, source):
         lines = source.split('\n')
diff --git a/generator/templates/apicpp.h b/generator/templates/apicpp.h
index 474289b..e203b7f 100644
--- a/generator/templates/apicpp.h
+++ b/generator/templates/apicpp.h
@@ -61,102 +61,115 @@
 
     template<typename Derived, typename CType>
     class ObjectBase {
-        public:
-            ObjectBase() = default;
-            ObjectBase(CType handle): mHandle(handle) {
+      public:
+        ObjectBase() = default;
+        ObjectBase(CType handle): mHandle(handle) {
+            if (mHandle) Derived::DawnReference(mHandle);
+        }
+        ~ObjectBase() {
+            if (mHandle) Derived::DawnRelease(mHandle);
+        }
+
+        ObjectBase(ObjectBase const& other)
+            : ObjectBase(other.Get()) {
+        }
+        Derived& operator=(ObjectBase const& other) {
+            if (&other != this) {
+                if (mHandle) Derived::DawnRelease(mHandle);
+                mHandle = other.mHandle;
                 if (mHandle) Derived::DawnReference(mHandle);
             }
-            ~ObjectBase() {
+
+            return static_cast<Derived&>(*this);
+        }
+
+        ObjectBase(ObjectBase&& other) {
+            mHandle = other.mHandle;
+            other.mHandle = 0;
+        }
+        Derived& operator=(ObjectBase&& other) {
+            if (&other != this) {
                 if (mHandle) Derived::DawnRelease(mHandle);
-            }
-
-            ObjectBase(ObjectBase const& other)
-                : ObjectBase(other.Get()) {
-            }
-            Derived& operator=(ObjectBase const& other) {
-                if (&other != this) {
-                    if (mHandle) Derived::DawnRelease(mHandle);
-                    mHandle = other.mHandle;
-                    if (mHandle) Derived::DawnReference(mHandle);
-                }
-
-                return static_cast<Derived&>(*this);
-            }
-
-            ObjectBase(ObjectBase&& other) {
                 mHandle = other.mHandle;
                 other.mHandle = 0;
             }
-            Derived& operator=(ObjectBase&& other) {
-                if (&other != this) {
-                    if (mHandle) Derived::DawnRelease(mHandle);
-                    mHandle = other.mHandle;
-                    other.mHandle = 0;
-                }
 
-                return static_cast<Derived&>(*this);
-            }
+            return static_cast<Derived&>(*this);
+        }
 
-            ObjectBase(std::nullptr_t) {}
-            Derived& operator=(std::nullptr_t) {
-                if (mHandle != nullptr) {
-                    Derived::DawnRelease(mHandle);
-                    mHandle = nullptr;
-                }
-                return static_cast<Derived&>(*this);
+        ObjectBase(std::nullptr_t) {}
+        Derived& operator=(std::nullptr_t) {
+            if (mHandle != nullptr) {
+                Derived::DawnRelease(mHandle);
+                mHandle = nullptr;
             }
+            return static_cast<Derived&>(*this);
+        }
 
-            explicit operator bool() const {
-                return mHandle != nullptr;
-            }
-            CType Get() const {
-                return mHandle;
-            }
-            CType Release() {
-                CType result = mHandle;
-                mHandle = 0;
-                return result;
-            }
-            static Derived Acquire(CType handle) {
-                Derived result;
-                result.mHandle = handle;
-                return result;
-            }
+        explicit operator bool() const {
+            return mHandle != nullptr;
+        }
+        CType Get() const {
+            return mHandle;
+        }
+        CType Release() {
+            CType result = mHandle;
+            mHandle = 0;
+            return result;
+        }
+        static Derived Acquire(CType handle) {
+            Derived result;
+            result.mHandle = handle;
+            return result;
+        }
 
-        protected:
-            CType mHandle = nullptr;
+      protected:
+        CType mHandle = nullptr;
     };
 
-    {% macro render_cpp_method_declaration(type, method) %}
-        {% set CppType = as_cppType(type.name) %}
-        DAWN_EXPORT {{as_cppType(method.return_type.name)}} {{method.name.CamelCase()}}(
-            {%- for arg in method.arguments -%}
-                {%- if not loop.first %}, {% endif -%}
-                {%- if arg.type.category == "object" and arg.annotation == "value" -%}
-                    {{as_cppType(arg.type.name)}} const& {{as_varName(arg.name)}}
-                {%- else -%}
-                    {{as_annotated_cppType(arg)}}
-                {%- endif -%}
-            {%- endfor -%}
-        ) const
-    {%- endmacro %}
+{% macro render_cpp_default_value(member) -%}
+    {%- if member.annotation in ["*", "const*", "const*const*"] and member.optional -%}
+        {{" "}}= nullptr
+    {%- elif member.type.category in ["enum", "bitmask"] and member.default_value != None -%}
+        {{" "}}= {{as_cppType(member.type.name)}}::{{as_cppEnum(Name(member.default_value))}}
+    {%- elif member.type.category == "native" and member.default_value != None -%}
+        {{" "}}= {{member.default_value}}
+    {%- else -%}
+        {{assert(member.default_value == None)}}
+    {%- endif -%}
+{%- endmacro %}
+
+{% macro render_cpp_method_declaration(type, method) %}
+    {% set CppType = as_cppType(type.name) %}
+    DAWN_EXPORT {{as_cppType(method.return_type.name)}} {{method.name.CamelCase()}}(
+        {%- for arg in method.arguments -%}
+            {%- if not loop.first %}, {% endif -%}
+            {%- if arg.type.category == "object" and arg.annotation == "value" -%}
+                {{as_cppType(arg.type.name)}} const& {{as_varName(arg.name)}}
+            {%- else -%}
+                {{as_annotated_cppType(arg)}}
+            {%- endif -%}
+            {{render_cpp_default_value(arg)}}
+        {%- endfor -%}
+    ) const
+{%- endmacro %}
 
     {% for type in by_category["object"] %}
         {% set CppType = as_cppType(type.name) %}
         {% set CType = as_cType(type.name) %}
         class {{CppType}} : public ObjectBase<{{CppType}}, {{CType}}> {
-            public:
-                using ObjectBase::ObjectBase;
-                using ObjectBase::operator=;
+          public:
+            using ObjectBase::ObjectBase;
+            using ObjectBase::operator=;
 
-                {% for method in native_methods(type) %}
-                    {{render_cpp_method_declaration(type, method)}};
-                {% endfor %}
+            {% for method in native_methods(type) %}
+                {{render_cpp_method_declaration(type, method)}};
+            {% endfor %}
 
-            private:
-                friend ObjectBase<{{CppType}}, {{CType}}>;
-                static DAWN_EXPORT void DawnReference({{CType}} handle);
-                static DAWN_EXPORT void DawnRelease({{CType}} handle);
+          private:
+            friend ObjectBase<{{CppType}}, {{CType}}>;
+            static DAWN_EXPORT void DawnReference({{CType}} handle);
+            static DAWN_EXPORT void DawnRelease({{CType}} handle);
         };
 
     {% endfor %}
@@ -167,7 +180,7 @@
                 const void* nextInChain = nullptr;
             {% endif %}
             {% for member in type.members %}
-                {{as_annotated_cppType(member)}};
+                {{as_annotated_cppType(member)}}{{render_cpp_default_value(member)}};
             {% endfor %}
         };