Make the JINJA2 template for the encoding library copy conditional.

A trial run of this for Chromium is here:
https://chromium-review.googlesource.com/c/chromium/src/+/1626401

This includes a .json configuration to use the facility to eliminate
one of the generated code copies.
https://chromium-review.googlesource.com/c/chromium/src/+/1626401/4/content/browser/devtools/protocol_config.json

A trial run for V8 is here:
https://chromium-review.googlesource.com/c/v8/v8/+/1627901

Change-Id: I3368b3f8937db89e6ed382ba34c8dda797c77fe8
diff --git a/code_generator.py b/code_generator.py
index 1e12343..b6e447d 100755
--- a/code_generator.py
+++ b/code_generator.py
@@ -101,6 +101,17 @@
             ".lib": False,
             ".lib.export_macro": "",
             ".lib.export_header": False,
+            # The encoding lib consists of encoding/encoding.h and
+            # encoding/encoding.cc in its subdirectory, which binaries
+            # may link / depend on, instead of relying on the
+            # JINJA2 templates lib/encoding_{h,cc}.template.
+            # In that case, |header| identifies the include file
+            # and |namespace| is the namespace it's using. Usually
+            # inspector_protocol_encoding but for v8's copy it's
+            # v8_inspector_protocol_encoding.
+            # TODO(johannes): Migrate away from lib/encoding_{h,cc}.template
+            #                 in favor of this.
+            ".encoding_lib": { "header": "", "namespace": []},
         }
         for key_value in config_values:
             parts = key_value.split("=")
diff --git a/gen_encoding_templates.py b/gen_encoding_templates.py
index 1733246..f773c4a 100755
--- a/gen_encoding_templates.py
+++ b/gen_encoding_templates.py
@@ -10,6 +10,8 @@
 This lets us edit the .cc / .h files, which is more pleasant
 (there are tests after all), and then update the templates
 mechanically.
+TODO(johannes): Migrate toward directly depending on encoding/encoding.{h,cc} to
+obviate the need for generating a copy in lib/encoding_{h,cc}.template.
 """
 
 def ReadBody(filename, system_includes, bodies):
@@ -52,6 +54,7 @@
       '// Generated by %s.\n' % filename,
       LICENSE,
       '\n']
+  contents.append('{% if config.encoding_lib.header == "" %}\n')
   if with_header_guard:
     contents.append('#ifndef {{"_".join(config.protocol.namespace)}}_%s_h\n' % with_header_guard)
     contents.append('#define {{"_".join(config.protocol.namespace)}}_%s_h\n' % with_header_guard)
@@ -69,6 +72,7 @@
   if with_header_guard:
     contents.append('#endif // !defined({{"_".join(config.protocol.namespace)}}_%s_h)' % with_header_guard)
   contents.append('\n')
+  contents.append('{% endif %}\n')
 
   open(filename, 'w').write(''.join(contents))
 
diff --git a/lib/Values_cpp.template b/lib/Values_cpp.template
index 7d3b907..bd349ce 100644
--- a/lib/Values_cpp.template
+++ b/lib/Values_cpp.template
@@ -6,6 +6,10 @@
 
 //#include "Values.h"
 
+{% if config.encoding_lib.header %}
+#include "{{config.encoding_lib.header}}"
+{% endif %}
+
 {% for namespace in config.protocol.namespace %}
 namespace {{namespace}} {
 {% endfor %}
@@ -64,6 +68,30 @@
 // to this constant.
 static constexpr int kStackLimitValues = 1000;
 
+{% if config.encoding_lib.namespace %}
+using {{"::".join(config.encoding_lib.namespace)}}::Error;
+using {{"::".join(config.encoding_lib.namespace)}}::Status;
+using {{"::".join(config.encoding_lib.namespace)}}::span;
+namespace cbor {
+using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::CBORTokenTag;
+using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::CBORTokenizer;
+using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::EncodeBinary;
+using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::EncodeDouble;
+using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::EncodeFalse;
+using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::EncodeFromLatin1;
+using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::EncodeFromUTF16;
+using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::EncodeIndefiniteLengthArrayStart;
+using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::EncodeIndefiniteLengthMapStart;
+using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::EncodeInt32;
+using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::EncodeNull;
+using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::EncodeStop;
+using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::EncodeString8;
+using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::EncodeTrue;
+using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::EnvelopeEncoder;
+using {{"::".join(config.encoding_lib.namespace + ['cbor'])}}::InitialByteForEnvelope;
+}  // namespace cbor
+{% endif %}
+
 // Below are three parsing routines for CBOR, which cover enough
 // to roundtrip JSON messages.
 std::unique_ptr<DictionaryValue> parseMap(int32_t stack_depth, cbor::CBORTokenizer* tokenizer);
diff --git a/lib/encoding_cpp.template b/lib/encoding_cpp.template
index 5b815ef..23cf19b 100644
--- a/lib/encoding_cpp.template
+++ b/lib/encoding_cpp.template
@@ -5,6 +5,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+{% if config.encoding_lib.header == "" %}
 
 #include <algorithm>
 #include <cassert>
@@ -2197,3 +2198,4 @@
 } // namespace {{namespace}}
 {% endfor %}
 
+{% endif %}
diff --git a/lib/encoding_h.template b/lib/encoding_h.template
index 406c4b8..2c6cfc1 100644
--- a/lib/encoding_h.template
+++ b/lib/encoding_h.template
@@ -5,6 +5,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+{% if config.encoding_lib.header == "" %}
 #ifndef {{"_".join(config.protocol.namespace)}}_encoding_h
 #define {{"_".join(config.protocol.namespace)}}_encoding_h
 
@@ -518,3 +519,4 @@
 } // namespace {{namespace}}
 {% endfor %}
 #endif // !defined({{"_".join(config.protocol.namespace)}}_encoding_h)
+{% endif %}