dawn.json changes for the flexible templates

  - Adds "_memtadata" that contains various metadata, the key
"api" represents the target of generating Web Standard API.

Rename webgpu.h to api.h and replace relative content with
metadata.

BUG=dawn:1201
Change-Id: I8b422ce4bd3f33d95e78d6c4b80f1310f7ac6726
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/70220
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Junwei Fu <junwei.fu@intel.com>
diff --git a/dawn.json b/dawn.json
index 29893b0..4954b29 100644
--- a/dawn.json
+++ b/dawn.json
@@ -17,6 +17,12 @@
 
     "_doc": "See docs/codegen.md",
 
+    "_metadata": {
+        "api": "WebGPU",
+        "c_prefix": "WGPU",
+        "namespace": "wgpu"
+    },
+
     "request adapter options": {
         "category": "structure",
         "extensible": "in",
diff --git a/docs/codegen.md b/docs/codegen.md
index 036305c..e6cb773 100644
--- a/docs/codegen.md
+++ b/docs/codegen.md
@@ -23,6 +23,13 @@
 
 Internally `dawn.json` is a dictionary from the "canonical name" of things to their definition. The "canonical name" is a space-separated (mostly) lower-case version of the name that's parsed into a `Name` Python object. Then that name can be turned into various casings with `.CamelCase()` `.SNAKE_CASE()`, etc. When `dawn.json` things reference each other, it is always via these "canonical names".
 
+The `"_metadata"` key in the JSON file is used by flexible templates for generating various Web Standard API that contains following metadata:
+
+ - `"api"` a string, the name of the Web API
+ - `"namespace"` a string, the namespace of C++ wrapper
+ - `"c_prefix"` (optional) a string, the prefix of C function and data type, it will default to upper-case of `"namespace"` if it's not provided.
+ - `"copyright_year"` (optional) a string, templates will use the the year of copyright.
+
 The basic schema is that every entry is a thing with a `"category"` key what determines the sub-schema to apply to that thing. Categories and their sub-shema are defined below. Several parts of the schema use the concept of "record" which is a list of "record members" which are a combination of a type, a name and other metadata. For example the list of arguments of a function is a record. The list of structure members is a record. This combined concept is useful for the dawn_wire generator to generate code for structure and function calls in a very similar way.
 
 Most items and sub-items can include a list of `"tags"`, which, if specified, conditionally includes the item if any of its tags appears in the `enabled_tags` configuration passed to `parse_json`. This is used to include and exclude various items for Dawn, Emscripten, or upstream header variants. Tags are applied in the "parse_json" step ([rather than later](https://docs.google.com/document/d/1fBniVOxx3-hQbxHMugEPcQsaXaKBZYVO8yG9iXJp-fU/edit?usp=sharing)): this has the benefit of automatically catching when, for a particular tag configuration, an included item references an excluded item.
diff --git a/generator/dawn_json_generator.py b/generator/dawn_json_generator.py
index 8783eb0..be2456a 100644
--- a/generator/dawn_json_generator.py
+++ b/generator/dawn_json_generator.py
@@ -23,6 +23,14 @@
 ############################################################
 
 
+class Metadata:
+    def __init__(self, metadata):
+        self.api = metadata['api']
+        self.namespace = metadata['namespace']
+        self.c_prefix = metadata.get('c_prefix', self.namespace.upper())
+        self.copyright_year = metadata.get('copyright_year', None)
+
+
 class Name:
     def __init__(self, name, native=False):
         self.native = native
@@ -397,6 +405,7 @@
         'enabled_tags': enabled_tags,
     }
     return {
+        'metadata': Metadata(json['_metadata']),
         'types': types,
         'by_category': by_category,
         'enabled_tags': enabled_tags,
@@ -494,24 +503,11 @@
         [name.CamelCase() for name in names[1:]])
 
 
-def as_cType(name):
+def as_cType(c_prefix, name):
     if name.native:
         return name.concatcase()
     else:
-        return 'WGPU' + name.CamelCase()
-
-
-def as_cTypeDawn(name):
-    if name.native:
-        return name.concatcase()
-    else:
-        return 'Dawn' + name.CamelCase()
-
-
-def as_cTypeEnumSpecialCase(typ):
-    if typ.category == 'bitmask':
-        return as_cType(typ.name) + 'Flags'
-    return as_cType(typ.name)
+        return c_prefix + name.CamelCase()
 
 
 def as_cppType(name):
@@ -575,17 +571,6 @@
     return any(tag in enabled_tags for tag in tags)
 
 
-def as_cEnum(type_name, value_name):
-    assert not type_name.native and not value_name.native
-    return 'WGPU' + type_name.CamelCase() + '_' + value_name.CamelCase()
-
-
-def as_cEnumDawn(type_name, value_name):
-    assert not type_name.native and not value_name.native
-    return ('DAWN' + '_' + type_name.SNAKE_CASE() + '_' +
-            value_name.SNAKE_CASE())
-
-
 def as_cppEnum(value_name):
     assert not value_name.native
     if value_name.concatcase()[0].isdigit():
@@ -593,47 +578,27 @@
     return value_name.CamelCase()
 
 
-def as_cMethod(type_name, method_name):
-    assert not type_name.native and not method_name.native
-    return 'wgpu' + type_name.CamelCase() + method_name.CamelCase()
-
-
-def as_cMethodDawn(type_name, method_name):
-    assert not type_name.native and not method_name.native
-    return 'dawn' + type_name.CamelCase() + method_name.CamelCase()
-
-
 def as_MethodSuffix(type_name, method_name):
     assert not type_name.native and not method_name.native
     return type_name.CamelCase() + method_name.CamelCase()
 
 
-def as_cProc(type_name, method_name):
-    assert not type_name.native and not method_name.native
-    return 'WGPU' + 'Proc' + type_name.CamelCase() + method_name.CamelCase()
-
-
-def as_cProcDawn(type_name, method_name):
-    assert not type_name.native and not method_name.native
-    return 'Dawn' + 'Proc' + type_name.CamelCase() + method_name.CamelCase()
-
-
-def as_frontendType(typ):
+def as_frontendType(metadata, typ):
     if typ.category == 'object':
         return typ.name.CamelCase() + 'Base*'
     elif typ.category in ['bitmask', 'enum']:
-        return 'wgpu::' + typ.name.CamelCase()
+        return metadata.namespace + '::' + typ.name.CamelCase()
     elif typ.category == 'structure':
         return as_cppType(typ.name)
     else:
-        return as_cType(typ.name)
+        return as_cType(metadata.c_prefix, typ.name)
 
 
-def as_wireType(typ):
+def as_wireType(metadata, typ):
     if typ.category == 'object':
         return typ.name.CamelCase() + '*'
     elif typ.category in ['bitmask', 'enum', 'structure']:
-        return 'WGPU' + typ.name.CamelCase()
+        return metadata.c_prefix + typ.name.CamelCase()
     else:
         return as_cppType(typ.name)
 
@@ -660,6 +625,46 @@
     return any(arg.type.category == 'callback' for arg in method.arguments)
 
 
+def make_base_render_params(metadata):
+    c_prefix = metadata.c_prefix
+
+    def as_cTypeEnumSpecialCase(typ):
+        if typ.category == 'bitmask':
+            return as_cType(c_prefix, typ.name) + 'Flags'
+        return as_cType(c_prefix, typ.name)
+
+    def as_cEnum(type_name, value_name):
+        assert not type_name.native and not value_name.native
+        return c_prefix + type_name.CamelCase() + '_' + value_name.CamelCase()
+
+    def as_cMethod(type_name, method_name):
+        assert not type_name.native and not method_name.native
+        return c_prefix.lower() + type_name.CamelCase() + method_name.CamelCase()
+
+    def as_cProc(type_name, method_name):
+        assert not type_name.native and not method_name.native
+        return c_prefix + 'Proc' + type_name.CamelCase() + method_name.CamelCase()
+
+    return {
+            'Name': lambda name: Name(name),
+            'as_annotated_cType': \
+                lambda arg: annotated(as_cTypeEnumSpecialCase(arg.type), arg),
+            'as_annotated_cppType': \
+                lambda arg: annotated(as_cppType(arg.type.name), arg),
+            'as_cEnum': as_cEnum,
+            'as_cppEnum': as_cppEnum,
+            'as_cMethod': as_cMethod,
+            'as_MethodSuffix': as_MethodSuffix,
+            'as_cProc': as_cProc,
+            'as_cType': lambda name: as_cType(c_prefix, name),
+            'as_cppType': as_cppType,
+            'as_jsEnumValue': as_jsEnumValue,
+            'convert_cType_to_cppType': convert_cType_to_cppType,
+            'as_varName': as_varName,
+            'decorate': decorate
+        }
+
+
 class MultiGeneratorFromDawnJSON(Generator):
     def get_description(self):
         return 'Generates code for various target from Dawn.json.'
@@ -698,35 +703,15 @@
 
         renders = []
 
-        RENDER_PARAMS_BASE = {
-            'Name': lambda name: Name(name),
-            'as_annotated_cType': \
-                lambda arg: annotated(as_cTypeEnumSpecialCase(arg.type), arg),
-            'as_annotated_cppType': \
-                lambda arg: annotated(as_cppType(arg.type.name), arg),
-            'as_cEnum': as_cEnum,
-            'as_cEnumDawn': as_cEnumDawn,
-            'as_cppEnum': as_cppEnum,
-            'as_cMethod': as_cMethod,
-            'as_cMethodDawn': as_cMethodDawn,
-            'as_MethodSuffix': as_MethodSuffix,
-            'as_cProc': as_cProc,
-            'as_cProcDawn': as_cProcDawn,
-            'as_cType': as_cType,
-            'as_cTypeDawn': as_cTypeDawn,
-            'as_cppType': as_cppType,
-            'as_jsEnumValue': as_jsEnumValue,
-            'convert_cType_to_cppType': convert_cType_to_cppType,
-            'as_varName': as_varName,
-            'decorate': decorate,
-        }
-
         params_dawn = parse_json(loaded_json,
                                  enabled_tags=['dawn', 'native', 'deprecated'])
+        metadata = params_dawn['metadata']
+        RENDER_PARAMS_BASE = make_base_render_params(metadata)
 
+        api_file_name = metadata.api.lower()
         if 'dawn_headers' in targets:
             renders.append(
-                FileRender('webgpu.h', 'src/include/dawn/webgpu.h',
+                FileRender('api.h', 'src/include/dawn/' + api_file_name + '.h',
                            [RENDER_PARAMS_BASE, params_dawn]))
             renders.append(
                 FileRender('dawn_proc_table.h',
@@ -761,14 +746,14 @@
             params_upstream = parse_json(loaded_json,
                                          enabled_tags=['upstream', 'native'])
             renders.append(
-                FileRender('webgpu.h', 'webgpu-headers/webgpu.h',
+                FileRender('api.h', 'webgpu-headers/' + api_file_name + '.h',
                            [RENDER_PARAMS_BASE, params_upstream]))
 
         if 'emscripten_bits' in targets:
             params_emscripten = parse_json(
                 loaded_json, enabled_tags=['upstream', 'emscripten'])
             renders.append(
-                FileRender('webgpu.h', 'emscripten-bits/webgpu.h',
+                FileRender('api.h', 'emscripten-bits/' + api_file_name + '.h',
                            [RENDER_PARAMS_BASE, params_emscripten]))
             renders.append(
                 FileRender('webgpu_cpp.h', 'emscripten-bits/webgpu_cpp.h',
@@ -804,9 +789,9 @@
                 params_dawn,
                 {
                     # TODO: as_frontendType and co. take a Type, not a Name :(
-                    'as_frontendType': lambda typ: as_frontendType(typ),
+                    'as_frontendType': lambda typ: as_frontendType(metadata, typ),
                     'as_annotated_frontendType': \
-                        lambda arg: annotated(as_frontendType(arg.type), arg),
+                        lambda arg: annotated(as_frontendType(metadata, arg.type), arg),
                 }
             ]
 
@@ -863,9 +848,9 @@
 
             wire_params = [
                 RENDER_PARAMS_BASE, params_dawn, {
-                    'as_wireType': as_wireType,
+                    'as_wireType': lambda type : as_wireType(metadata, type),
                     'as_annotated_wireType': \
-                        lambda arg: annotated(as_wireType(arg.type), arg),
+                        lambda arg: annotated(as_wireType(metadata, arg.type), arg),
                 }, additional_params
             ]
             renders.append(
diff --git a/generator/templates/webgpu.h b/generator/templates/api.h
similarity index 78%
rename from generator/templates/webgpu.h
rename to generator/templates/api.h
index d305dd2..f03dbae 100644
--- a/generator/templates/webgpu.h
+++ b/generator/templates/api.h
@@ -14,14 +14,15 @@
 //*
 //*
 //* This template itself is part of the Dawn source and follows Dawn's license
-//* but the generated file is used for "WebGPU native". The template comments
+//* but the generated file is used for "Web API native". The template comments
 //* using //* at the top of the file are removed during generation such that
 //* the resulting file starts with the BSD 3-Clause comment.
 //*
 //*
 // BSD 3-Clause License
 //
-// Copyright (c) 2019, "WebGPU native" developers
+{% set year = metadata.copyright_year if metadata.copyright_year else 2019 %}
+// Copyright (c) {{year}}, "{{metadata.api}} native" developers
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -48,26 +49,27 @@
 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#ifndef WEBGPU_H_
-#define WEBGPU_H_
+#ifndef {{metadata.api.upper()}}_H_
+#define {{metadata.api.upper()}}_H_
 
-#if defined(WGPU_SHARED_LIBRARY)
+{% set c_prefix = metadata.c_prefix %}
+#if defined({{c_prefix}}_SHARED_LIBRARY)
 #    if defined(_WIN32)
-#        if defined(WGPU_IMPLEMENTATION)
-#            define WGPU_EXPORT __declspec(dllexport)
+#        if defined({{c_prefix}}_IMPLEMENTATION)
+#            define {{c_prefix}}_EXPORT __declspec(dllexport)
 #        else
-#            define WGPU_EXPORT __declspec(dllimport)
+#            define {{c_prefix}}_EXPORT __declspec(dllimport)
 #        endif
 #    else  // defined(_WIN32)
-#        if defined(WGPU_IMPLEMENTATION)
-#            define WGPU_EXPORT __attribute__((visibility("default")))
+#        if defined({{c_prefix}}_IMPLEMENTATION)
+#            define {{c_prefix}}_EXPORT __attribute__((visibility("default")))
 #        else
-#            define WGPU_EXPORT
+#            define {{c_prefix}}_EXPORT
 #        endif
 #    endif  // defined(_WIN32)
-#else       // defined(WGPU_SHARED_LIBRARY)
-#    define WGPU_EXPORT
-#endif  // defined(WGPU_SHARED_LIBRARY)
+#else       // defined({{c_prefix}}_SHARED_LIBRARY)
+#    define {{c_prefix}}_EXPORT
+#endif  // defined({{c_prefix}}_SHARED_LIBRARY)
 
 #include <stdint.h>
 #include <stddef.h>
@@ -85,7 +87,7 @@
 #define WGPU_ARRAY_LAYER_COUNT_UNDEFINED (0xffffffffUL)
 #define WGPU_MIP_LEVEL_COUNT_UNDEFINED (0xffffffffUL)
 
-typedef uint32_t WGPUFlags;
+typedef uint32_t {{c_prefix}}Flags;
 
 {% for type in by_category["object"] %}
     typedef struct {{as_cType(type.name)}}Impl* {{as_cType(type.name)}};
@@ -99,30 +101,30 @@
         {{as_cEnum(type.name, Name("force32"))}} = 0x7FFFFFFF
     } {{as_cType(type.name)}};
     {% if type.category == "bitmask" %}
-        typedef WGPUFlags {{as_cType(type.name)}}Flags;
+        typedef {{c_prefix}}Flags {{as_cType(type.name)}}Flags;
     {% endif %}
 
 {% endfor -%}
 
-typedef struct WGPUChainedStruct {
-    struct WGPUChainedStruct const * next;
-    WGPUSType sType;
-} WGPUChainedStruct;
+typedef struct {{c_prefix}}ChainedStruct {
+    struct {{c_prefix}}ChainedStruct const * next;
+    {{c_prefix}}SType sType;
+} {{c_prefix}}ChainedStruct;
 
-typedef struct WGPUChainedStructOut {
-    struct WGPUChainedStructOut * next;
-    WGPUSType sType;
-} WGPUChainedStructOut;
+typedef struct {{c_prefix}}ChainedStructOut {
+    struct {{c_prefix}}ChainedStructOut * next;
+    {{c_prefix}}SType sType;
+} {{c_prefix}}ChainedStructOut;
 
 {% for type in by_category["structure"] %}
     typedef struct {{as_cType(type.name)}} {
         {% set Out = "Out" if type.output else "" %}
         {% set const = "const " if not type.output else "" %}
         {% if type.extensible %}
-            WGPUChainedStruct{{Out}} {{const}}* nextInChain;
+            {{c_prefix}}ChainedStruct{{Out}} {{const}}* nextInChain;
         {% endif %}
         {% if type.chained %}
-            WGPUChainedStruct{{Out}} chain;
+            {{c_prefix}}ChainedStruct{{Out}} chain;
         {% endif %}
         {% for member in type.members %}
             {{as_annotated_cType(member)}};
@@ -155,9 +157,9 @@
     );
 {% endfor %}
 
-typedef void (*WGPUProc)(void);
+typedef void (*{{c_prefix}}Proc)(void);
 
-#if !defined(WGPU_SKIP_PROCS)
+#if !defined({{c_prefix}}_SKIP_PROCS)
 
 typedef WGPUInstance (*WGPUProcCreateInstance)(WGPUInstanceDescriptor const * descriptor);
 typedef WGPUProc (*WGPUProcGetProcAddress)(WGPUDevice device, char const * procName);
@@ -174,9 +176,9 @@
     {% endfor %}
 
 {% endfor %}
-#endif  // !defined(WGPU_SKIP_PROCS)
+#endif  // !defined({{c_prefix}}_SKIP_PROCS)
 
-#if !defined(WGPU_SKIP_DECLARATIONS)
+#if !defined({{c_prefix}}_SKIP_DECLARATIONS)
 
 WGPU_EXPORT WGPUInstance wgpuCreateInstance(WGPUInstanceDescriptor const * descriptor);
 WGPU_EXPORT WGPUProc wgpuGetProcAddress(WGPUDevice device, char const * procName);
@@ -184,7 +186,7 @@
 {% for type in by_category["object"] if len(c_methods(type)) > 0 %}
     // Methods of {{type.name.CamelCase()}}
     {% for method in c_methods(type) %}
-        WGPU_EXPORT {{as_cType(method.return_type.name)}} {{as_cMethod(type.name, method.name)}}(
+        {{c_prefix}}_EXPORT {{as_cType(method.return_type.name)}} {{as_cMethod(type.name, method.name)}}(
             {{-as_cType(type.name)}} {{as_varName(type.name)}}
             {%- for arg in method.arguments -%}
                 , {{as_annotated_cType(arg)}}
@@ -193,10 +195,10 @@
     {% endfor %}
 
 {% endfor %}
-#endif  // !defined(WGPU_SKIP_DECLARATIONS)
+#endif  // !defined({{c_prefix}}_SKIP_DECLARATIONS)
 
 #ifdef __cplusplus
 } // extern "C"
 #endif
 
-#endif // WEBGPU_H_
+#endif // {{metadata.api.upper()}}_H_